I have two methods: a()
and b()
. While I'm fine with multiple threads accessing any of the methods at the same time (that is desirable), I do not want any threads to enter a()
while b()
is being executed.
How do I do that?
Lets say there are 4 threads and Thread 1
is accessing A()
. What I want is all of the 4 threads should not use B()
.
Mutual Exclusive helps keep threads from interfering with one another while sharing data. It can be achieved by using the following three ways: By Using Synchronized Method. By Using Synchronized Block.
MutuallyExclusiveFrame subclass of Frame. It simply creates a new MutuallyExclusiveMenu and shows the text indicating which option in the menu is currently selected. The MutuallyExclusiveMenu class is an alternative to a Panel with a bunch of mutually exclusive radio buttons.
Mutually exclusive is a statistical term describing two or more events that cannot happen simultaneously. It is commonly used to describe a situation where the occurrence of one outcome supersedes the other. For example, war and peace cannot coexist at the same time. This makes them mutually exclusive.
10. Which will contain the body of the thread? run();
CHECK UPDATE at the bottom - I don't think this approach can work. Leaving it for information.
You could use a Semaphore:
b()
, a thread trying to execute a()
will block until the execution of b()
is over.b()
and a second thread tries to run b()
it will be able toa()
while b()
is not being executed both will runNote: once a thread is in a()
and has passed the "semaphore test", another thread can start running b()
before the end of a()
The principle should work but I have not tested it.
private final Semaphore inB = new Semaphore(1);
public void a() throws InterruptedException {
inB.acquire(); //blocks until no thread is in b any longer
//now we are good to go and execute a()
//release the semaphore immediately for other threads who want to run a()
inB.release();
//rest of your code here
}
public void b() {
//does not block to allow 2 thread running b() simultaneously
boolean needToRelease = inB.tryAcquire();
//rest of your code
//if the permit was acquired, release it to allow threads to run a()
if (needToRelease) {
inB.release();
}
}
EDIT
Your intention is not clear and your question has been edited because one of your comments says that you want a()
and b()
to be mutually exclusive (many threads can run either a()
or b()
in parallel, but a()
and b()
should never be run in parallel). In that case, you can use the same logic with 2 semaphores inA
and inB
.
UPDATE => BUG
As pointed out by @yshavit in a comment to another answer, there is a race condition in the code in the following scenario:
a()
and acquires inB
b()
and fails to acquire inB
inB
a()
and manages to acquire inB
although T2 is running b()
It seems that this can't be achieved with Sempahores only. This answer gives a better solution.
Exception handling ommitted for simplicity:
public class Test {
private final Object lock = new Object();
private int counterA;
private int counterB;
public void a() {
synchronized(lock) {
while(counterB > 0) {
lock.wait();
}
++counterA;
}
// do work
synchronized(lock) {
--counterA;
lock.notifyAll();
}
}
public void b() {
synchronized(lock) {
while(counterA > 0) {
lock.wait();
}
++counterB;
}
// do work
synchronized(lock) {
--counterB;
lock.notifyAll();
}
}
}
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