I am on my way learning Java multithread programming. I have a following logic:
Suppose I have a class A
class A {
ConcurrentMap<K, V> map;
public void someMethod1 () {
// operation 1 on map
// operation 2 on map
}
public void someMethod2 () {
// operation 3 on map
// operation 4 on map
}
}
Now I don’t need synchronization of the operations in “someMethod1” or “someMethod2”. This means if there are two threads calling “someMethod1” at the same time, I don’t need to serialize these operations (because the ConcurrentMap will do the job).
But I hope “someMethod1” and “someMethod2” are mutex of each other, which means when some thread is executing “someMethod1”, another thread should wait to enter “someMethod2” (but another thread should be allowed to enter “someMethod1”).
So, in short, is there a way that I can make “someMethod1” and “someMethod2” not mutex of themselves but mutex of each other?
I hope I stated my question clear enough…
Thanks!
I tried a couple attempts with higher-level constructs, but nothing quite came to mind. I think this may be an occasion to drop down to the low level APIs:
One glaring problem with the above is that it can lead to thread starvation. For instance,
someMethod1()is running (and blockingsomeMethod2()s), and just as it’s about to finish, another thread comes along and invokessomeMethod1(). That proceeds just fine, and just as it finishes another thread startssomeMethod1(), and so on. In this scenario,someMethod2()will never get a chance to run. That’s actually not directly a bug in the above code; it’s a problem with your very design needs, one which a good solution should actively work to solve. I think a fair AbstractQueuedSynchronizer could do the trick, though that is an exercise left to the reader. 🙂Finally, I can’t resist but to interject an opinion: given that
ConcurrentHashMapoperations are pretty darn quick, you could be better off just putting a single mutex around both methods and just being done with it. So yes, threads will have to queue up to invokesomeMethod1(), but each thread will finish its turn (and thus let other threads proceed) extremely quickly. It shouldn’t be a problem.