I was learning about the java threads ( synchronization and locks ) but somehow i was not able to find the difference between these two things.
// Two different instances of SyncExample
Thread a1 = new Thread(new SyncExample(), "A");
Thread b1 = new Thread(new SyncExample(), "B");
// Same instance is passed to both the threads
SyncExample syn = new SyncExample();
Thread a2 = new Thread(syn, "A");
Thread b2 = new Thread(syn, "B");
// I believe in total 4 stacks are built.
a1.start();
b1.start();
a2.start();
b2.start();
public class SyncExample implements Runnable {
Object obj = new Object();
@Override
public void run() {
this.myName();
}
private void myName() {
synchronized (obj) {
System.out.print("Define" + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
System.out.println(ex);
}
System.out.print("tly" + Thread.currentThread().getName());
}
System.out.println(" Maybe" + Thread.currentThread().getName());
}
}
public class SyncExample implements Runnable {
Object obj = new Object();
@Override
public void run() {
this.myName();
}
private void myName() {
synchronized (obj) {
System.out.print("Define" + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
System.out.println(ex);
}
System.out.print("tly" + Thread.currentThread().getName());
}
System.out.println(" Maybe" + Thread.currentThread().getName());
}
}
But the problem here is when i run this example using the
1 - Same reference output is :
DefineAtlyA MaybeA
DefineBtlyB MaybeB
2 - 2 different instances :
DefineADefineBtlyAtlyB MaybeB
MaybeA
Can ayone explain me what difference it makes when we pass the runnable target to Thread class 1. Same instance 2. Different instance
In you code, when you pass two different instances (of SyncExample class), each instance has its own lock object (held by variable obj). As there are two different lock objects, each thread acquires a lock and executes in parallel, resulting in interleaved output of thread A and B (DefineADefineBtlyAtlyB MaybeB MaybeA).
Whereas when you pass the same instance, there is just one instance of SyncExample class. As a result, there is just one instance of the lock object (held by variable obj). Hence this lock object will be shared between the two threads. Due to this sharing, only one thread (say T1) will be able to enter the synchronized block; the other thread (say T2) would wait till T1 exists the synchronized block. Therefore in your execution, you see all print statements for thread A first, followed by all statements for thread B (DefineAtlyA MaybeA DefineBtlyB MaybeB).
If I were to generalized this: when you pass different instances, only static variables would affect the parallel execution of the threads, but when you pass a single instance, both the static and class level variables (such as the obj variable in your code) will affect the parallel execution of the threads.
The output should hint you on the difference.
When you pass in the same SyncExample to two different threads, only one of them will be able to acquire lock on obj and execute the code in synchronized block.
When you pass in two different SyncExample objects, both of the threads are able to execute simultaneously because they are synchronizing on different objects.
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