import java.math.BigInteger;
class Numbers {
final static int NUMBER = 2;
final static int POWER = 4;
static long msecs;
static BigInteger result;
static Boolean done = false;
public static void main(String[] args) {
BigInteger number = BigInteger.valueOf(NUMBER);
result = number;
//Boolean done = false;
Runnable pow = () -> {
System.out.println(number + " pow " + POWER + " = " + number.pow(POWER));
synchronized (done) {
done = true;
done.notifyAll();
}
};
Runnable sum = () -> {
for(int i = 2; i<POWER; i=i*i) {
result = result.multiply(result);
}
System.out.println(number + " sum " + POWER + " = " + result);
synchronized (done) {
done = true;
done.notifyAll();
}
};
Runnable time = () -> {
for(msecs = 0; true; msecs++) {
try {
Thread.sleep(1);
} catch(InterruptedException e) {
//nic
}
}
};
Thread timet = new Thread(time);
Thread sumt = new Thread(sum);
Thread powt = new Thread(pow);
timet.start();
powt.start();
synchronized (done) {
while(!done) {
try {
done.wait();
} catch (InterruptedException e) {
//nic
}
}
}
timet.interrupt();
powt.interrupt();
System.out.println("Pow time " + msecs + " msecs.");
done = false;
timet.start();
sumt.start();
try {
synchronized (done) {
while (!done) {
done.wait();
}
}
} catch (InterruptedException e) {
//nic
}
timet.interrupt();
sumt.interrupt();
System.out.println("Sum time " + msecs + " msecs.");
}
}
I want to check time differences between those two methods, but done.notifyAll()
keeps throwing IllegalMonitorStateException
.
Problem is here:
synchronized (done) {
done = true;//<---problem
done.notifyAll();
}
Since you are assigning new value to done
it means you are executing notifyAll
on Boolean.TRUE
but your synchronization block is using monitor of Boolean.FALSE
. And since notifyAll
requires thread to posses monitor of object on which it is executed it throws IllegalMonitorStateException
.
So don't change value of object on which you synchronize. Also avoid synchronizing on objects which are available for all classes (public constants /literals) since you are risking that other people will have same idea and will also use them in their synchronization which could cause you some pain.
Locks should be accessible only from within class to they belong. So take example from Jon Skeet (What is the difference between synchronized on lockObject and using this as the lock?) and synchronize on your own
private final Object lock = new Object();
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