Is it that monitor in Java does not restrict access to instance variables and only to the methods which are declared synchronized or code in synchronized statements?
I have created two threads, thread y
invokes sync()
method, which is declared synchronized while thread r
invokes unsync()
method which is not declared synchronized. Both invoke methods on shared object s
.
Thread r
is able to modify the instance variable of object s
while the monitor or lock of that object is still being held by the thread y
.
Is it that the monitor in Java does not restrict access to instance variables, and only to the methods which are declared synchronized or code in synchronized statements?
public class Stuff {
private int a = 10;
public synchronized void sync() {
long t1 = System.currentTimeMillis();
System.out.println("Okay, I am in sync() method. "
+ "I will be waiting for 10 seconds. Current Time = "
+ System.currentTimeMillis());
while (System.currentTimeMillis() - t1 < 10000);
System.out.println("Okay, I have waited for 10 seconds. Current time is "
+ System.currentTimeMillis()
+ ". Now I will exit from sync() method, a = " + this.a);
}
public void unsync() {
System.out.println("Alright, I am in unsync() method. The current time is "
+ System.currentTimeMillis());
this.a = this.a + 1;
System.out.println(". The time of exit from unsync() method is "
+ System.currentTimeMillis());
}
}
class T1 extends Thread {
Stuff s;
public T1(Stuff s) {
this.s = s;
}
public void run() {
s.sync();
}
}
class T2 extends Thread {
Stuff s;
public T2(Stuff s) {
this.s = s;
}
public void run() {
s.unsync();
}
}
class Main {
public static void main(String args[]) throws Exception {
Stuff s = new Stuff();
T1 y = new T1(s);
T2 r = new T2(s);
y.start();
Thread.sleep(2000);
r.start();
}
}
The output of the program is below:
Okay, I am in sync() method. I will be waiting for 10 seconds. Current Time = 1358801766310 Alright, I am in unsync() method. The current time is 1358801768343. The time of exit from unsync() method is 1358801768343 Okay, I have waited for 10 seconds. Current time is 1358801776310. Now I will exit from sync() method, a = 11
Yes. Holding the monitor of an object prevents another thread from executing another block of code or synchronized on the same object. If a method is not synchronized, any thread can call it at any time, whether another thread holds a monitor or not.
Every access to a shared stated, even read-only accessed, must be synchronized if there's a chance that at least one thread modifies this shared state.