简体   繁体   中英

Unable to understand the behaviour of thread synchronization in following java code

When I execute the following piece of code

public class ThreadTalk {
    public static void main(String[] args) {
        SimpleThread obj = new SimpleThread();
        Thread t = new Thread(obj, "NewThread");
        t.start();
        synchronized (obj) {
            System.out.println("In Synchronized BLOCK");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Out of Synchronized BLOCK");
        }
    }
}

class SimpleThread implements Runnable {
    public void run() {
        System.out.println("The thread running now " + Thread.currentThread());
        for (int i = 0; i < 10; i++) {
            System.out.println("The val of i= " + i);
        }
    }
}

The output that I am getting is

In Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9
Out of Synchronized BLOCK

where as I am expecting an output like

In Synchronized BLOCK
Out of Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9

If I am putting a Lock on the SimpleThread object using the Synchronized block of main thread, how is my NewThread running when main thread is going to sleep.I mean shouldn't the NewThread wait till the Main thread has removed the lock on the SimpleThread object, as both threads are running on the same object.

run() and/or start() do not take any locks. They just run code. You need to actually have SimpleTread take the same lock as the main thread for those two threads to synchronize in some fashion.

Rather than try to synchronize on the the Runnable object, I think best practice would be to explicitly declare a separate object to use as a lock.

class ThreadTalk{
   public static void main(String[] args){
     Object lock = new Object();
     SimpleThread obj=new SimpleThread( lock );
     Thread t=new Thread(obj,"NewThread");
     t.start();

    synchronized(lock){
      System.out.println("In Synchronized BLOCK");
      try{
        Thread.sleep(5000);
        }catch(InterruptedException e){
         e.printStackTrace();
        }
      System.out.println("Out of Synchronized BLOCK");
    }
  }
}
class SimpleThread implements Runnable{
    private final Object lock;
    public SimpleThread( Object lock ) { this.lock = lock;}
    public void run(){
      synchronized( lock ) {
         System.out.println("The thread running now "+Thread.currentThread());
         for(int i=0;i<10;i++){
           System.out.println("The val of i= "+i);
         }
       }
    }
}

You need to synchronize in both threads on the same object (the so-called "monitor") to make them mutually exclusive.

The simplest way to do that is to make the run() method itself synchronized :

class SimpleThread implements Runnable {
    // See the synchronized modifier on the next line
    public synchronized void run() {
        System.out.println("The thread running now " + Thread.currentThread());
        for (int i = 0; i < 10; i++) {
            System.out.println("The val of i= " + i);
        }
    }
}

You would also need to make sure that you synchronize on the SimpleThread object before you start it in a Thread, so you need to move the t.start(); statement inside the synchronized (obj) { block. If you don't do that, the two threads are still improperly synchronized, and there's no telling which thread will run first.

synchronized block does not do what you think. It means that only one thread can be inside of it (or rather inside any synchronized block on the same object) at the same time. In your case, there is only one (main) thread inside the block. The other one is executing different code. That is expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM