Recently I have read Bruce Eckel (Thinking in Java), and I have found some problem: block synchronized(Object) locking Class! not Object of this Class. This code proves mentioned above :
public class Main {
public static void main(String[] args) {
Sync s = new Sync();
new Thread(new Runnable() {
@Override
public void run() {
s.go();
}
}, "First").start();
new Thread(new Runnable() {
@Override
public void run() {
s.go();
}
}, "Second").start();
}
}
class Sync {
private Writer w1, w2;
public Sync() {
w1 = new Writer();
w2 = new Writer();
}
public void go() {
synchronized (w2) {
w1.log(Thread.currentThread().getName() + "...1");
//!All threads must performance parallel, but they do it consistently.
w2.log(Thread.currentThread().getName() + "...2");
//All threads must performance parallel, and they do it.
}
}
}
class Writer {
public void log(Object obj) {
for (int i = 0; i < 5; i++) {
lgn(obj);
try {
TimeUnit.MILLISECONDS.sleep(750);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have locked w2, but locking got w2, and!! w1. Why? w1 and w2 is different objects! Why are they locking together?
But all sources is talking about locking in synchronized OBJECT, not Class! If I've mistaked, can you help me understand how it works?
Output
First...1
First...1
First...1
First...1
First...1
First...2
First...2
First...2
First...2
First...2
Second...1
Second...1
Second...1
Second...1
Second...1
Second...2
Second...2
Second...2
Second...2
Second...2
Expected output
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...2
First...2
First...2
First...2
First...2
Second...2
Second...2
Second...2
Second...2
Second...2
P.S Sorry for my English(
synchronized (w2)
means we create a Lock with w2, not locking object w2. You can create a lock with any other object, and the code in synchronized block still be locked.
class Sync {
private Writer w1, w2;
private Object whatEver;
public Sync() {
w1 = new Writer();
w2 = new Writer();
whatEver = new Object();
}
public void go() {
synchronized (whatEver) {
w1.log(Thread.currentThread().getName() + "...1");
//!All threads must performance parallel, but they do it consistently.
w2.log(Thread.currentThread().getName() + "...2");
//All threads must performance parallel, and they do it.
}
}
}