简体   繁体   English

如何编写线程安全操作并使它们原子化?

[英]How to compose thread safe operations and make them atomic?

Let's take a thread safe class like LinkedBlockingDeque : 让我们来看一个像LinkedBlockingDeque这样的线程安全类:

BlockingQueue<Task> taskQueue = new LinkedBlockingDeque<Task>();

I know that operations like take and put are thread safe, so they respect the happened-before relationship. 我知道诸如takeput类的操作是线程安全的,因此它们尊重事前发生的关系。

But what if I want to compose some operations to make them atomic? 但是,如果我想编写一些操作使其原子化怎么办? Like this: 像这样:

if(taskQueue.size() == 1) {
   /*Do a lot of things here, but I do not want other threads
     to change the size of the queue here with take or put*/
}
//taskQueue.size() must still be equal to 1

If it was a not thread safe class, I could do something like this: 如果它不是线程安全的类,则可以执行以下操作:

synchronized(taskQueue) {
  if(taskQueue.size() == 1) {
    /*Do a lot of things here, but I do not want other threads
      to change the size of the queue here with take or put*/
  }
  //taskQueue.size() must still be equal to 1
}

But it is not that simple, I do not think that the implementations of take and put use the object lock. 但这不是那么简单,我不认为takeput的实现使用对象锁。

How do you handle this scanario? 您如何处理此scanario?

How do you handle this scenario? 您如何处理这种情况?

In general, you cannot "compose" operations on the concurrent data structures without using external locking of some kind. 通常,如果不使用某种类型的外部锁定,就无法在并发数据结构上“组合”操作。 And when you do that, you you reintroduce the concurrency bottleneck that you were trying to avoid by using the concurrent data structure. 然后,您会通过使用并发数据结构来重新引入要避免的并发瓶颈。

In this case, you are correct. 在这种情况下,您是正确的。 The LinkedBlockingDeque class uses a private lock object for synchronization, etcetera. LinkedBlockingDeque类使用私有锁对象进行同步等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM