class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
System.out.println("rahul");
}
// synchronize calls to call()
public void run() {
synchronized(target) { // synchronized block
target.call(msg);
}
}
}
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
in this program when i use a synchronized block without System.out.print("rahul") it prints perfect output but when i put these unnecessary statement of SOP("rahul") output gets distorted why is it happening instead of synchronization?
Your starting a thread from a constructor and passing an instance of this into the thread. Caller has not been fully constructed so its member variables may not have been initialized yet in the run method.
The extra println is allowing the bug to be seen.
Runnables should define the work, and calling code should handle the threads. Runnables should not run themselves.
You should also sync on final variables.
} }
Each individual
System.out.println()
is internally synchronized, so no output from a singleprintln()
call should get garbled.However, there's no synchronization across multiple calls to
println()
. If multiple threads concurrently write to the same print stream, the relative order in which their messages will appear is not guaranteed.If you require a particular ordering, you'll have to synchronize the threads yourself.
I will assume that the
System.out.println
messages cause your 3Caller
messages to change order:There is no guaranteed order here. Even if the
"Hello"
Caller
object is constructed first, that doesn't mean that itsrun()
method will actually be executed first. There is still a race to thesynchronized
block inside each of the threads. The"World"
string could be printed first for example.By adding your series of
System.out.println("rahul");
calls, it sounds like you are affecting the timing of the program. The underlyingPrintStream
object is synchronized so it will affect the locking in the other threads even if they are locking on another object. Any synchronization crosses a memory barrier which causes cache flushing and memory copying between threads and can affect their run order, speed, etc.. If you ran your program 1000 times you would see many different output combinations. That's the nature of race conditions -- they are unpredictable.