下面是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) {}
}
}
}
答案 0 :(得分:60)
答案位于java.lang.Object.wait(long),其文档显示:
[...]此方法使当前线程(称为T)将自己置于该对象的等待集中,然后放弃对该对象的所有同步声明。 [...]
答案 1 :(得分:32)
使用
Thread.sleep(5000);
使当前正在执行的线程在指定的毫秒数内进入睡眠状态(暂时停止执行),这取决于系统计时器和调度程序的精度和准确性。线程不会失去任何监视器的所有权。
答案 2 :(得分:13)
Oracle Tutorials中的以下引号说明了这种情况:
调用
wait
时,线程释放锁并挂起 执行。
此外,只有一个线程可以执行受同一对象保护的synchronized
块!在您的示例中调用wait
会释放该锁,从而允许另一个线程获取该锁。