为什么另一个线程在同步部分尚未完成时可以访问阻塞对象?

消息“main Thread”在消息“new Thread”之前打印,尽管消息“new Thread”的方法位于包含 print* 方法的对象的同步部分中。


    Test test = new Test();

    new Thread(() -> {

        try {

            synchronized (test) {

                Thread.sleep(5000);

                test.printMessage();

            }

        } catch (InterruptedException e) {}

    }).start();

    Thread.sleep(1000);

    test.printAnotherMessage();

}


public void printMessage() {

    System.out.println("new Thread");

}


public void printAnotherMessage() {

    System.out.println("main Thread");

}

}


梦里花落0921
浏览 116回答 2
2回答

斯蒂芬大帝

printAnotherMessage在此示例中,休眠 5 秒的同步块之间没有同步,这就是主线程休眠 1 秒然后main Thread无需任何等待即可打印的原因。您可能打算创建printAnotherMessage一个同步方法。在这种情况下,主线程将等待,直到另一个线程完成测试对象上同步块的执行。

守着一只汪

没有同步,test.printAnotherMessage();因此假设时机正确,它将首先执行。4 秒已经很多了,应该足够了。synchronized (test) {    test.printAnotherMessage();}Thread.sleep不过,这很少是一个好的选择。更合适的方法是Test test = new Test();new Thread(() -> {    synchronized (test) {        test.printMessage();        test.notify();    }}).start();synchronized (test) {    test.wait();    test.printAnotherMessage();}我在这里玩一个危险的游戏,因为我假设主线程将进入同步块并在创建另一个线程并进入其同步块wait() 之前执行。这是合理的,因为创建线程需要一些时间。Test test = new Test();new Thread(() -> {    try {        // a lot of time to let the main thread execute wait()        Thread.sleep(500);         synchronized (test) {            test.printMessage();            test.notify();        }    } catch (InterruptedException e) {}}).start();synchronized (test) {    test.wait();    test.printAnotherMessage();}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java