【问题标题】:Two threads executing synchronized block simultaneously两个线程同时执行同步块
【发布时间】:2019-02-27 20:21:18
【问题描述】:

下面是Thread 进入同步块,等待 5 秒然后退出的代码。我同时启动了两个Thread 实例。

期望线程之一将拥有同步对象上的锁,而另一个将等待。 5秒后,当锁拥有者退出时,等待线程将执行。

但实际上,两个线程都在同时执行同步块并同时退出。

预期输出:

Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...

实际输出:

Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...

我错过了什么吗?

import java.text.SimpleDateFormat;
import java.util.Date;

public class Test2 {
public static void main(String[] args) {
    MyRunnable m = new MyRunnable();
    Thread t = new Thread(m);
    Thread t1 = new Thread(m);
    t.start();
    t1.start();
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            try {
                SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
                Date date = new Date(System.currentTimeMillis());
                System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
                wait(5000);
                date = new Date(System.currentTimeMillis());
                System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
            } catch(InterruptedException ie) {}
        }
    }
}

【问题讨论】:

  • 无关:请停止使用Date 类。 java.time 包太棒了。

标签: java multithreading synchronized thread-synchronization


【解决方案1】:

答案在于java.lang.Object.wait(long),其文档中写道:

[...] 该方法使当前线程(称为 T)将自己置于该对象的等待集中,然后放弃对该对象的所有同步声明。 [...]

【讨论】:

    【解决方案2】:

    使用

    Thread.sleep(5000);
    

    JavaDocs for Thread.sleep:

    使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。线程不会失去对任何监视器的所有权。

    【讨论】:

      【解决方案3】:

      Oracle Tutorials 的以下引用解释了这种情况:

      wait被调用时,线程释放锁并挂起 执行。

      此外,只有一个线程可以执行由同一对象保护的synchronized 块!在您的示例中调用 wait 会释放锁,从而允许另一个线程获取锁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-02
        • 1970-01-01
        • 2014-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多