Java - 同步线程 - 输出顺序错误

2023-11-29

在玩了一年 Java 之后,我正在阅读《Java 完整参考》(第 9 版)。到目前为止,我对这本书很满意,但我现在在同步线程方面遇到了一个非常奇怪的问题:

package syncro;

class Callme {
    void call(String msg) {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
        System.out.println("]");
    }
}

class Caller1 implements Runnable {
    String msg;
    Callme target;
    Thread t;

    public Caller1(Callme targ, String s) {
        target = targ;
        msg = s;
        t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {
        synchronized (target) { // SYNC BLOCK
            target.call(msg);
        }

    }
}

public class Syncronized {
    public static void main(String[] args) {
        Callme target = new Callme();
        Caller1 ob1 = new Caller1(target, "Hello");
        Caller1 ob2 = new Caller1(target, "Synchronized");
        Caller1 ob3 = new Caller1(target, "World");

        try {
            ob1.t.join();
            ob2.t.join();
            ob3.t.join();
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
    }

}

它打印出:

[Hello]
[World]
[Synchronized]

我不明白这怎么可能。还值得一提的是,如果我交换线路

 Caller1 ob2 = new Caller1(target, "Synchronized");
 Caller1 ob3 = new Caller1(target, "World");

(构造函数在“Synchronized”之前使用字符串“World”调用) 它会打印

[Hello]
[Synchronized]
[World]

正如我一开始所预料的那样。

我在这里没有找到这样的问题,所以我希望我做得对......谢谢!


简短的回答是,你唯一的事情就是synchronized块保证是你的 3 个调用Callme.call将是互斥的 - 你不会(例如)最终得到所有 3 个线程Thread.sleep同时呼叫。它不保证这三个调用发生的顺序,事实上,多次运行未修改的代码有可能(尽管不太可能)导致您的 3 个单词在任何特定运行中以任何顺序输出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java - 同步线程 - 输出顺序错误 的相关文章

随机推荐