Oracle's tutorial Intrinsic Locks and Synchronization says:
Intrinsic[Monitor] locks play a role in both aspects of synchronization: enforcing exclusive access to an object's state
I assumed no value in an object could be manipulated by two threads at once, should one thread be executing a 'synchronized' method.
As such, I was surprised (although relieved for the purposes of what I am looking to do) when the following code had the following output. I wasn't entirely sure what to expect, however I figured an error or some point might occur.
From what I can understand, 'synchronized' merely acts to restrict access to an object, if another thread is requesting the monitor state for that object -- but not if that other thread is altering a one off value. Is this correct?
public class HelloWorld implements Runnable{
Thread t1;
Thread t2;
int val1 = 0;
int val2 = 0;
public static void main(String[] args) {
HelloWorld h1 = new HelloWorld();
h1.t1 = new Thread(h1);
h1.t2 = new Thread(h1);
h1.t1.start();
h1.t2.start();
}
@Override
public void run() {
System.out.println("STARTED");
System.gc();
Thread currentThread = Thread.currentThread();
if (currentThread == this.t1) {
this.locker(); //This is a synchronized method, incrementing val1
}
if (currentThread == this.t2) {
this.adder(); //This is a non-synchronized method, incrementing val2
}
}
private synchronized void locker() {
for(int i = 0; i < 3; i++){
val1++;
System.out.println("LOCKER: " + this.val1);
}
}
private void adder() {
while(this.val2 < 3) {
this.val2++;
System.out.println("ADDER: " + this.val2);
}
synchronized(this) {
//Synchronize for final output
System.out.println("FINAL");
System.out.println(val1);
System.out.println(val2);
}
}
}
STARTED
STARTED
ADDER: 1
LOCKER: 1
LOCKER: 2
ADDER: 2
LOCKER: 3
ADDER: 3
FINAL
3
3