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!
How to find if two events are mutually exclusive? If two events are mutually exclusive then the probability of both the events occurring at the same time is equal to zero. P(A and B) = 0.
What are Mutually Exclusive Events? In statistics and probability theory, two events are mutually exclusive if they cannot occur at the same time. The simplest example of mutually exclusive events is a coin toss. A tossed coin outcome can be either head or tails, but both outcomes cannot occur simultaneously.
Britannica Dictionary definition of MUTUALLY EXCLUSIVE. : related in such a way that each thing makes the other thing impossible : not able to be true at the same time or to exist together. War and peace are mutually exclusive. [=war and peace cannot exist at the same time] mutually exclusive events.
Mutually Exclusive Projects is the term which is used generally in the capital budgeting process where the companies choose a single project on the basis of certain parameters out of the set of the projects where acceptance of one project will lead to rejection of the other projects.
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:
EDIT: I actually think you're trying to set up a problem which is inherently tricky (see second to last paragraph) and probably not needed (see last paragraph). But that said, here's how it could be done, and I'll leave the color commentary for the end of this answer.
private int someMethod1Invocations = 0;
private int someMethod2Invocations = 0;
public void someMethod1() {
synchronized(this) {
// Wait for there to be no someMethod2 invocations -- but
// don't wait on any someMethod1 invocations.
// Once all someMethod2s are done, increment someMethod1Invocations
// to signify that we're running, and proceed
while (someMethod2Invocations > 0)
wait();
someMethod1Invocations++;
}
// your code here
synchronized (this) {
// We're done with this method, so decrement someMethod1Invocations
// and wake up any threads that were waiting for that to hit 0.
someMethod1Invocations--;
notifyAll();
}
}
public void someMethod2() {
// comments are all ditto the above
synchronized(this) {
while (someMethod1Invocations > 0)
wait();
someMethod2Invocations++;
}
// your code here
synchronized(this) {
someMethod2Invocations--;
notifyAll();
}
}
One glaring problem with the above is that it can lead to thread starvation. For instance, someMethod1()
is running (and blocking someMethod2()
s), and just as it's about to finish, another thread comes along and invokes someMethod1()
. That proceeds just fine, and just as it finishes another thread starts someMethod1()
, 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 ConcurrentHashMap
operations 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 invoke someMethod1()
, but each thread will finish its turn (and thus let other threads proceed) extremely quickly. It shouldn't be a problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With