.NET线程 – 分配需要锁定

我有一些multithreading代码,我想增加一点的性能,所以我想知道我是否可以摆脱锁。

我有一个现场成员:

private IList status; 

它在这样的线程中更新:

 status = GetUpdatedStatus(); 

它在另一个线程中使用,如下所示:

 var currentStatus = status; 

所以问题是,如果没有锁定两个赋值语句,上面会产生任何问题吗?

我想我能看到的唯一情况是currentStatus为null,但是我再次希望赋值有点线程安全(或者它已经更改了引用)

你是对的。 您将看到作业,否则您将看不到它。 引用的赋值(和读取)总是“primefaces的”(最后它是因为32位机器引用是32位,所以可以primefaces方式完成,而64位机器(运行64位应用程序)引用是64位,所以可以primefaces方式完成。唯一的例外是尝试在32位机器上写/读长(64位)。你必须使用Interlocked.Read / Interlocked.Exchange)

通常应将状态声明为volatile ,以便每个线程只能看到最新版本。 你应该读到这个: http : //www.albahari.com/threading/非常好!

如果您不信任我,请阅读Do We Really Need Locks and Barriers? 这里http://www.albahari.com/threading/part4.aspx

啊……我忘记了…世界恨你,所以有一点要知道不稳定:有时它不起作用:-) :-)在另一个例子的同一页中读取section The volatile keyword ,红色框下面的部分。 Notice that applying volatile doesn't prevent a write followed by a read from being swapped, and this can create brainteasers 。 最后,唯一可以确定的方法是使用Interlocked.Exchange来编写和使用Interlocked.Exchange读取内容或者使用同步保护读取和写入部分(如lock )或者使用Thread.MemoryBarrier填充程序(但是请不要试试看,你会失败,你甚至不知道为什么。 保证锁中完成的所有读取和写入都将在锁定中完成,而不是在锁定之前或之后。

参考写入是保证primefaces的,因此只需要检查两件事:

  • 在紧密循环中使用 – 如果需要注意更改,可能需要添加volatile
  • 双重更新; 如果您(例如)通过引用交换进行添加/删除,则应使用Interlocked.CompareExchange确保不丢失数据; 继续重新应用您的更改,直到您赢得交换

 object snapshot, newValue; do { snapshot = field; // do something based on that; create a clone // with more/less data for example newValue = ...; } while (!ReferenceEquals( Interlocked.CompareExchange(ref field, newValue, snapshot), snapshot));