0

I have three synchronized methods in a class when i try to execute all of them by starting different threads, I am unable to see the synchronized output, no lock is obtained on object & i could see in output all the threads are executed simultaneously. Below is my code. Inputs are appreciated. Thanks

public class DisplayMessage {

public static synchronized void sayHello(String name) throws InterruptedException{
    for(int i=1; i<=10;i++){
        Thread.sleep(1000);
        System.out.println("How are you"+name);
    }
}
public synchronized void sayHello1(String name2,int j){
    for(int i=1; i<=10;i++){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("How are you Hello1  :: "+name2+ " Age " + j);
    }
}
public synchronized void sayHello2(String name3,String lastname){
    for(int i=1; i<=10;i++){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("How are you Hello 2 :: "+ name3 + " lastname " +lastname);
    }
}

} Thread class :

public class MyThread extends Thread {

String name;


MyThread(String name) {

    this.name = name;
}

public void run() {

    try {
        DisplayMessage.sayHello(name);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

} Thread2 class : public class MyThread2 extends Thread {

String name2;
String name3;

int age;
DisplayMessage dm;

MyThread2(DisplayMessage dm, String name2, int age) {
    this.dm = dm;
    this.name2 = name2;
    this.age = age;
}

public void run() {

    dm.sayHello1(name2, age);

}

} Thread3 class:

package Synchronization.classlock;

public class MyThread3 extends Thread {

String name3;
String lastname;
int age;

DisplayMessage dm2;

MyThread3(DisplayMessage dm, String name3, String lastname) {
    this.dm2 = dm;
    this.name3 = name3;
    this.lastname = lastname;
}

public void run() {

    dm2.sayHello2(name3, lastname);
}

}

Democlass with main method spawning different threads public class SynchronizationDemo {

public static void main(String[] args) {
    DisplayMessage dm=new DisplayMessage();
    MyThread t1= new MyThread("steve");
    MyThread t2=new MyThread("Anitha");
    MyThread2 t3=new MyThread2(dm," Amit", 31);
    MyThread3 t4=new MyThread3(dm," Arit ","urkude");
    t1.start();
    t2.start();
    t3.start();
    t4.start();

}

}

below are the outputs:

How are yousteve How are you Hello1 :: Amit Age 31 How are you Hello1 :: Amit Age 31 How are yousteve How are yousteve How are you Hello1 :: Amit Age 31 How are yousteve How are you Hello1 :: Amit Age 31 How are yousteve How are you Hello1 :: Amit Age 31 How are yousteve How are you Hello1 :: Amit Age 31 How are yousteve How are you Hello1 :: Amit Age 31 How are you Hello1 :: Amit Age 31 How are yousteve How are yousteve How are you Hello1 :: Amit Age 31 How are yousteve How are you Hello1 :: Amit Age 31 How are youAnitha How are you Hello 2 :: Arit lastname urkude How are youAnitha How are you Hello 2 :: Arit lastname urkude How are youAni How are you Hello 2 :: Arit lastname urkude How are youAni How are you Hello 2 :: Arit lastname urkude How are you Hello 2 :: Arit lastname urkude How are youAni How are youAni How are you Hello 2 :: Arit lastname urkude How are youAni How are you Hello 2 :: Arit lastname urkude How are you Hello 2 :: Arit lastname urkude How are youAni How are youAni How are you Hello 2 :: Arit lastname urkude How are youAni How are you Hello 2 :: Arit lastname urkude

GoodToLearn
  • 41
  • 1
  • 5
  • You are synchornizing on a static method as well as 2 instance methods, is that what you want?. Why not use just one method and see how synchronized works – TheLostMind May 09 '17 at 09:03

2 Answers2

2

The output you are seeing is perfectly valid according to your code. MyThread is using DisplayMessage.sayHello() method, which is static and therefore synchronized on the DisplayMessage.class object. Usage of synchronized keyword on static method is equivalent to:

public static void sayHello(String name) throws InterruptedException{
    synchronized(DisplayMessage.class) {
        for(int i=1; i<=10;i++){
            Thread.sleep(1000);
            System.out.println("How are you"+name);
        }
    }
}

On the other hand two other threads, MyThread2 and MyThread3 are calling non-static methods - sayHello1 and sayHello2, which are synchronized on this. Usage of synchronized keyword in this case is equivalent to:

public void sayHello1(String name2,int j){
    synchronized(DisplayMessage.this) {
        for(int i=1; i<=10;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("How are you Hello1  :: "+name2+ " Age " + j);
        }
    }
}

So, your output contains steve and Amit running concurently followed by Anitha and Arit running concurently, which is expected as code is synchronized on two different objects.

Piotrek
  • 79
  • 3
1

synchronized keyword added to the static method is to the current *.java file corresponding to the class lock; and synchronized keyword added to the no-static method is to this object lock. Although the two locks are different, but this object lock and class lock can be re-entered each other.

handsp
  • 127
  • 5