Sahil
Sahil

Reputation: 96

Testing the Synchronize in java

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

Answers (4)

user177800
user177800

Reputation:

There is so much wrong with this it is hard to know where to start.

  1. You don't actually ever synchronize on anything between the different threads. You are calling testme on completely different objects they will never interact.

  2. 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.

  3. 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?

  4. Shared data must be marked volatile otherwise threads may or may not see updates to the data.

  5. Learn to use AtmoicInteger for cases like this where you want to share data safely.

  6. Don't start Threads manually like this learn how to use ExecutorService.

Upvotes: 1

coder
coder

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

John B
John B

Reputation: 32969

Timeline option 1 - could happen in either order (15 first or 17 first)

  • r1: set s to 15
  • r2: set s to 17
  • r1: enter lock using 17
  • r2: enter lock using 17 is blocked
  • r1: exits lock
  • r2: enters lock
  • r2: exits lock

Timeline option 2:

  • r1: set s to 15
  • r1: enter lock using 15
  • r2: set s to 17
  • r2: enter lock using 17 (not blocked because lock is on different value)
  • r1: exits lock
  • r2: exits lock

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

TheMightyWiwi
TheMightyWiwi

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

Related Questions