Steve
Steve

Reputation: 3

What is wrong with the synchronization in following code

SYNCHRONIZATION

I have declared a class b which has a synchronized method which is accessed in class c:

class b {
    String msg;

    public synchronized void foo() {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000); // Threads go to sleeep

        } catch (InterruptedException e) {
            System.out.println("Caught" + e);
        }
        System.out.println("]");
    }
}

class a implements Runnable {
    b ob;

    Thread t;

    a(String msg, b obb) {
        ob = obb;
        ob.msg = msg;
        t = new Thread(this); // creating a thread
        t.start();
    }

    public void run() {
        ob.foo(); // calling method of class b
    }

    public static void main(String... a) {
        b obb = new b();
        a ob = new a("Hello", obb); /* PASSING */
        a ob1 = new a("Synch", obb); /* THE */
        a ob2 = new a("World", obb);/* MESSAGE */

        try {
            ob.t.join();
            ob1.t.join();
            ob2.t.join();
        } catch (InterruptedException e) {
            System.out.println("Caught" + e);
        }
    }
}

I am expecting the output:

[Hello]
[Synch]
[World]

But the code gives:

[World]
[World]
[World]

Help me with some suggestions. I am a naive JAVA user.

Upvotes: 0

Views: 99

Answers (3)

pnathan
pnathan

Reputation: 713

use the following code to get the expected answer.

class b { // String msg;

public void foo(String msg) {
    System.out.print("[" + msg);
    try {
        Thread.sleep(1000); // Threads go to sleeep

    } catch (InterruptedException e) {
        System.out.println("Caught" + e);
    }
    System.out.println("]");
}

}

public class Threading implements Runnable {

    b ob;
String msg;
Thread t;

Threading(String message, b obb) {
    ob = obb;
    msg = message;
    t = new Thread(this); // creating a thread
    t.start();
}

public void run() {
    synchronized (ob) {
        ob.foo(msg); // calling method of class b
    }

}

public static void main(String... a) {
    b obb = new b();
    Threading ob = new Threading("Hello", obb); /* PASSING */
    Threading ob2 = new Threading("World", obb); /* THE */
    Threading ob1 = new Threading("Synch", obb);/* MESSAGE */

    try {
        ob.t.join();
        ob1.t.join();
        ob2.t.join();
    } catch (InterruptedException e) {
        System.out.println("Caught" + e);
    }
}

}

Upvotes: 1

Dia
Dia

Reputation: 271

First of all reformat your code. It is very hard to read. Second when you call ob.msg = msg; it overrites msg value in ob and as it is not synchronized so you cannot actually predict what the output will be.

Upvotes: 0

Subir Kumar Sao
Subir Kumar Sao

Reputation: 8401

In the code you have set ob.msg=msg; msg gets overridden by the threads. So you have the same message for all the Threads.

In the constructor of each Thread of class a you are passing the same object of class b. Now all three threads are setting the value of msg of the instance of class b. So one value overrides the other. What you have is the value set by last thread i.e. World.

IMO: Save the msg as an instance variable in each thread and pass it to the foo method as a parameter.

And please follow Java naming convention i.e. Camel Casing

Upvotes: 0

Related Questions