Replacing volatile with a synchronized block does not work
I went through this tutorial. I figured out the use of the volatile keyword. But when I tried to achieve the same result without using the volatile keyword with performing an operation on a cons variable with a synchronized block, it doesn't work. It throws an IllegalMonitorStateException. Here is the modified code I have tried.
public class VolatileTest {
private static Integer MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
@Override
public void run() {
synchronized(MY_INT){
int local_value = MY_INT;
while ( local_value < 5){
if( local_value!= MY_INT){
System.out.format("Got Change for MY_INT : {0}", MY_INT);
local_value= MY_INT;
try {
MY_INT.wait();
} catch (Exception e) { e.printStackTrace(); }}
}
}
}
}
static class ChangeMaker extends Thread{
@Override
public void run() {
synchronized(MY_INT){
int local_value = MY_INT;
while (MY_INT <5){
System.out.format("Incrementing MY_INT to {0}", local_value+1);
MY_INT = ++local_value;
try {
MY_INT.notify();
} catch (Exception e) { e.printStackTrace(); }
}
}
}}}
What I want to know in this case is a volatile replaceable synchronized block, if so how to do it? Thank.
source to share
The problem is here:
MY_INT = ++local_value;
MY_INT
is a variable Integer
and when you assign a new value to it, the object you are blocking is here:
synchronized(MY_INT){
will be different from the object you notify here:
MY_INT.notify();
... and this will throw an exception.
The solution is to create a lock object static final
. Obviously, this means you can't assign it ... but that's the whole point!
source to share