首页 新闻 搜索 专区 学院

这段代码能保证多线程安全吗?

0
悬赏园豆:20 [已解决问题] 解决于 2012-08-16 09:00
<pre>&nbsp;<span>public</span>&nbsp;<span>class</span>&nbsp;<span>DoubleCacheQueue</span>&lt;T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>public</span>&nbsp;DoubleCacheQueue()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>public</span>&nbsp;T&nbsp;Dequeue()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;t&nbsp;=&nbsp;<span>default</span>(T);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(readQueue.Count&nbsp;&gt;&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t=&nbsp;readQueue.Dequeue();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeQueue&nbsp;=&nbsp;<span>Interlocked</span>.Exchange&lt;<span>Queue</span>&lt;T&gt;&gt;(<span>ref</span>&nbsp;readQueue,&nbsp;writeQueue);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return</span>&nbsp;t;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>public</span>&nbsp;<span>void</span>&nbsp;Enqueue(T&nbsp;item)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeQueue.Enqueue(item);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>public</span>&nbsp;<span>int</span>&nbsp;Count<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>get</span>&nbsp;{&nbsp;<span>return</span>&nbsp;readQueue.Count;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//读缓冲</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>private</span>&nbsp;<span>Queue</span>&lt;T&gt;&nbsp;readQueue&nbsp;=&nbsp;<span>new</span>&nbsp;<span>Queue</span>&lt;T&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//写缓冲</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>private</span>&nbsp;<span>Queue</span>&lt;T&gt;&nbsp;writeQueue&nbsp;=&nbsp;<span>new</span>&nbsp;<span>Queue</span>&lt;T&gt;();<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;}</pre> <p>问下大家,这段代码能保证多线程安全吗?</p>
问题补充: 不好意思,问题提的有点模糊,我补充下: 我应用的场景就是只有2个线程,我想实现一个lock free的队列 一个读线程不停的Dequeue 一个写线程不停的Enqueue 在只有2个线程一个单线程读和一个单线程写的情况下,能不能双线程安全?
garry的主页 garry | 菜鸟二级 | 园豆:495
提问于:2011-01-17 15:26
< >
分享
最佳答案
1

三个方法均非线程安全。

即使只有读线程不停的Dequeue 一个写线程不停的Enqueue,也有问题。 因为Interlocked.Exchange只是解决了赋值操作的并发问题,当其执行后,二个线程访问的是相同一个对象readQueue,焉能不出问题。

收获园豆:20
James Leng | 菜鸟二级 |园豆:230 | 2011-11-13 21:21

Exchange是交换,交换后,俩个线程各自操作自己的Queue,不是操作同一个Queue啊?

garry | 园豆:495 (菜鸟二级) | 2013-01-23 15:20
其他回答(3)
0

No。

队列只剩一项数据时,并发去Dequeue可能会出异常。Queue<T>考虑常规则应用的效率,应该不会提供并发检查。

heros | 园豆:561 (小虾三级) | 2011-01-18 10:52
0

个人认为应该不是线程安全的

Dequeue和Enqueue方法都是直接操作Queue,而对Queue的线程安全MSDN上说法如下:

此类型的公共静态成员是线程安全的。但不能保证任何实例成员是线程安全的。

所以个人认为应该不是线程安全的

六芒星 | 园豆:627 (小虾三级) | 2011-01-18 11:02

内部是俩个q,不是一个,每个线程各操作一个

支持(0) 反对(0) garry | 园豆:495 (菜鸟二级) | 2013-02-02 15:21
0

非线程安全,不能确保在多线程情况下的读写。

但是只是一个线程读,一个线程写的情况下可以。

根据业务应用来设计自己的数据结构操作,不一定非要完全线程安全。

在实施服务器连接管理器时,频繁的上线、下线对于服务器的连接管理器hashtable加锁势必会增加服务器的开销,使得效率低下

Shiaupo | 园豆:272 (菜鸟二级) | 2011-01-19 17:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册