user1232138
user1232138

Reputation: 5541

understanding how synchronized keyword works

In the following code I was expecting only one of the two threads to enter the halt() function and then halt the program. But it seems as if both the threads are entering into the synchronized halt() function. Why could this be happening??

package practice;

class NewThread implements Runnable {
  String name; // name of thread
  Thread t;
  boolean suspendFlag;

  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    suspendFlag = false;
    t.start(); // Start the thread
  }

  // This is the entry point for thread.
  public void run() {
    try {
      for(int i = 15; i > 0; i--) {
        System.out.println(name + ": " + i);
        Thread.sleep(200);
        Runtime r = Runtime.getRuntime();
        halt();
      }
    } catch (InterruptedException e) {
      System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
  }

  synchronized void halt() throws InterruptedException
  {
      System.out.println(name + " entered synchronized halt");
      Runtime r = Runtime.getRuntime();
      Thread.sleep(1000);
      r.halt(9);
      System.out.println(name + " exiting synchronized halt"); // This should never execute
  }
}

class Practice{
  public static void main(String args[]) {
    NewThread ob1 = new NewThread("One");
    NewThread ob2 = new NewThread("Two");

    // wait for threads to finish
    try {
      System.out.println("Waiting for threads to finish.");
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }

    System.out.println("Main thread exiting."); // This should never execute
  }
}

Upvotes: 1

Views: 559

Answers (5)

dcernahoschi
dcernahoschi

Reputation: 15230

The synchronization is done on each object. If you have 2 objects, 2 threads might get into the halt() method simultaneously. You can make the method static to achieve what you want. By making it static the lock will be put on the corresponding Class object (NewThreadOne.class) which is unique regarding of the number of instances of NewThreadOne.

Upvotes: 2

BloodRed
BloodRed

Reputation: 38

Its not recommended to use String object as lock in java synchronized block because string is immutable object and literal string and interned string gets stored in String pool. so by any chance if any other part of code or any third party library used same String as there lock then they both will be locked on same object despite being completely unrelated which could result in unexpected behavior and bad performance. instead of String object its advised to use new Object() for Synchronization in Java on synchronized block.

Upvotes: 1

Dan D.
Dan D.

Reputation: 32391

The synchronized method is using this for locking. In your case, you have 2 different objects, as you are building 2 thread instances, so you are not locking on the same object. In order to have the synchronization behavior you expected, you need to make the halt method static.

Upvotes: 1

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33534

You have Used 2 objects for 2 threads as their monitor lock....

So your code is working fine, with each thread accessing the lock of its own object to access the halt() method....

In synchonized keyword, you achieve the lock of an object, by which the thread gets an access to the synchronized methods or atomic statements within that class......

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533442

synchronized does not lock a method, it locks an object.

You have one method but two objects. Each thread locks its own object and calls halt().

Upvotes: 7

Related Questions