Reputation: 884
I am trying to understand synchronization, but while it tried to implement it,I am getting an ambiguous result, while trying to implement synchronized, Have a look at it.
By obesrving the output, it is clear that two threads are able to access the synchronized block simultaneously. Guide me where am I Going wrong.
Output:
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Program:
package com.StackOverFlow.Doubts3;
public class Dbts5 {
public static void main(String[] args) {
Display d1= new Display();
MyThreads th1= new MyThreads(d1, "Thread1");
th1.start();
MyThreads th2= new MyThreads(d1, "Thread2");
th2.start();
}
}
class MyThreads extends Thread{
Display d;
String name;
@Override
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
d.show();
}
}
public MyThreads() {}
MyThreads(Display d, String name){
this.d=d;
this.name=name;
}
}
class Display{
synchronized void show(){
System.out.println("Display class show method called by- "+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(Edited) Expected output:
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
.
.
.
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Upvotes: 1
Views: 134
Reputation: 53879
Your synchronized block is not accessed concurrently.
What you observe is:
If you add some trace, you will see better that show
is never entered twice before exiting:
synchronized void show(){
System.out.println(Thread.currentThread().getName() + " In");
// do show
System.out.println(Thread.currentThread().getName() + " Out");
}
And you will see:
Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
// ...
Thread-1 In
Display class show method called by- Thread-1
Thread-1 Out
// ...
Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
If you want the threads to call show
n times before releasing the lock, then you should use synchronized
around the for-loop
:
@Override
public void run() {
showSeveralTimes(10);
}
And in Display
:
synchronized void showSeveralTimes(int n) {
for(int i = 0 ; i < n ; ++i) {
show();
}
}
Upvotes: 2
Reputation: 16051
Quoting from an Oracle tutorial:
- First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
- Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
So Thread-n
runs, returns, Thread-n
runs, returns, ad infinitum (or 10 in this case)
Upvotes: 0
Reputation: 500953
By obesrving the output, it is clear that two threads are able to access the synchronized block simultaneously.
No, there's absolutely no evidence of that. Let's consider the following output:
Display class show method called by- Thread-0
Display class show method called by- Thread-1
Here:
Thread-0
calls show()
, enters the synchronized
block, prints out the message, exits from show()
(leaving the synchronized
block).Thread-1
calls show()
, enters the synchronized
block, prints out the message, exits from show()
(leaving the synchronized
block).and so on.
If you want to see the threads blocking each other, put synchronized
around the loop:
synchronized(d) {
for (int i = 0; i < 10; i++) {
d.show();
}
}
Upvotes: 2