为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

梦里花落0921 2023-08-09 17:26:34
消息“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");}}
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

printAnotherMessage在此示例中,休眠 5 秒的同步块之间没有同步,这就是主线程休眠 1 秒然后main Thread无需任何等待即可打印的原因。

您可能打算创建printAnotherMessage一个同步方法。在这种情况下,主线程将等待,直到另一个线程完成测试对象上同步块的执行。


查看完整回答
反对 回复 2023-08-09
?
守着一只汪

TA贡献1872条经验 获得超3个赞

没有同步,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();

}


查看完整回答
反对 回复 2023-08-09
  • 2 回答
  • 0 关注
  • 114 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信