以下代码中的同步有什么问题

时间:2013-10-11 08:57:07

标签: java synchronization

同步

我已声明class b有一个同步方法,可在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);
        }
    }
}

我期待输出:

[Hello]
[Synch]
[World]

但是代码给出了:

[World]
[World]
[World]

帮我提一些建议。我是一个天真的JAVA用户。

3 个答案:

答案 0 :(得分:1)

使用以下代码获得预期答案。

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实现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);
    }
}

}

答案 1 :(得分:0)

在您设置的代码ob.msg=msg; msg被线程覆盖。所以你对所有线程都有相同的信息。

在类a的每个Thread的构造函数中,您传递的是类b的相同对象。现在,所有三个线程都设置了类msg实例的b的值。所以一个值会覆盖另一个值。你拥有的是最后一个帖子设置的值,即World

IMO:将msg保存为每个线程中的实例变量,并将其作为参数传递给foo方法。

请遵循Java命名约定,即Camel Casing

答案 2 :(得分:0)

首先重新格式化您的代码。这很难读。 第二,当你调用ob.msg = msg;时,它会超过ob中的msg值,因为它没有同步,所以你实际上无法预测输出是什么。