两个线程同时执行同步块
Posted
技术标签:
【中文标题】两个线程同时执行同步块【英文标题】: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
包太棒了。
【参考方案1】:
答案在于java.lang.Object.wait(long),其文档中写道:
[...] 该方法使当前线程(称为 T)将自己置于该对象的等待集中,然后放弃对该对象的所有同步声明。 [...]
【讨论】:
【参考方案2】:使用
Thread.sleep(5000);
JavaDocs for Thread.sleep:
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。线程不会失去对任何监视器的所有权。
【讨论】:
【参考方案3】:Oracle Tutorials 的以下引用解释了这种情况:
当
wait
被调用时,线程释放锁并挂起 执行。
此外,只有一个线程可以执行由同一对象保护的synchronized
块!在您的示例中调用 wait
会释放锁,从而允许另一个线程获取锁。
【讨论】:
以上是关于两个线程同时执行同步块的主要内容,如果未能解决你的问题,请参考以下文章