Kami
Kami

Reputation: 1109

How to compose thread safe operations and make them atomic?

Let's take a thread safe class like 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.

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.

How do you handle this scanario?

Upvotes: 1

Views: 211

Answers (1)

Stephen C
Stephen C

Reputation: 719709

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 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.

Upvotes: 3

Related Questions