Reputation: 96
Here I have taken a String lock for testing purpose to know that how actual flow of two thread behaves but it gives me unpredictable output.
Here is the Code...
public class SyncCall {static SyncTesting sync1 = new SyncTesting();
static Runnable r1=new Runnable() {
public void run() {
try {
sync1.s=new String("15");
Thread.currentThread().setName("Thread1");
sync1.testme();
// Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("sync1");
} catch (Exception ex) {
Logger.getLogger(SyncCall.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
static Runnable r2=new Runnable() {
public void run() {
try {
sync1.s=new String("17");
Thread.currentThread().setName("Thread2");
sync1.testme();
//Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("sync2");
} catch (Exception ex) {
Logger.getLogger(SyncCall.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
public static void main(String args[]){
Thread th1=new Thread(r1);
Thread th2=new Thread(r2);
th1.start();
th2.start();
}
}
public class SyncTesting {String s=new String("abc");
//final Object s=new Object();
public void testme(){
synchronized(s){
try {
System.out.println("Hello");
System.out.println(s);
// s=new String("18");
Thread.sleep(1000);
System.out.println("Hello after sleep" +Thread.currentThread().getName());
} catch (Exception ex) {
Logger.getLogger(SyncTesting.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
The Output I get is like sometimes...
Hello 17 Hello 17 Hello after sleepThread1 Thread1 sync1 Hello after sleepThread2 Thread2 sync2
And Sometimes...
Hello 15 Hello 15 Hello after sleepThread2 Thread2 sync2 Hello after sleepThread1 Thread1 sync1
I know that the diffrent output i get because of the String object as a lock in syncronization but i want to know that why two threads give same value of string yet other thread changing that string value.
Upvotes: 1
Views: 844
Reputation:
You don't actually ever synchronize
on anything between the different threads. You are calling testme
on completely different objects they will never interact.
calling new String("abc")
is incorrect usage of the object. calling new
on String
guarantees that instances will not be the same, even for the same data. String a = new String("abc"); String b = new String("abc"); a == b is false
.
You have to use the exact same instance of the same lock object in all synchronized
blocks, that should be pretty obvious, otherwise how is it supposed to know what to block access to?
Shared data must be marked volatile
otherwise threads may or may not see updates to the data.
Learn to use AtmoicInteger
for cases like this where you want to share data safely.
Don't start Threads
manually like this learn how to use ExecutorService
.
Upvotes: 1
Reputation: 4466
When same S value (17) is printed
T1 --> sets S=15 --->enters Syn Block --> prints Hello --> prints S (T2 has set S=17)
T2 -------------> sets S=17 --->enters Syn Block --> print Hello --> prints S
When same S value (15) is printed
T1 ------------> sets S=15 --->enters Syn Block --> prints Hello --> prints S
T2 --> sets S=17 ---> enters Syn Block --> print Hello --> prints S (S=15 set before T2 prints S)
When diff values are printed
T1 --> sets S=15 --->enters Syn Block --> prints Hello --> prints S
T2 -----------------------------------------------------------------> sets S=17 --->enters Syn Block --> print Hello --> prints S
The issue here is that you changing the lock object itself. So two threads can execute same code block even if its sync
Upvotes: 1
Reputation: 32969
Timeline option 1 - could happen in either order (15 first or 17 first)
Timeline option 2:
The issue here is that you have changed the reference on which you are locking so it is possible for each thread to lock on a different value on entry. Also with multi-threading just because one thread sets a value doesn't mean it will continue to see that value if another thread is able to change it.
Upvotes: 0
Reputation: 1
I guess that If the second thread changes the value before the first one uses it, it remains changed, otherwise the second thread sets the value first and the first one changes it
Upvotes: 0