我有两个线程t0和t1,下面分别在代码部分Run_0和Run1中发布了runnables。我想要做的是,当t0写入或执行持续7秒的任务时,t1应该等待。当时 经过7秒后,应通知t1继续工作。我尝试使用wait()和notify()来做到这一点,但在运行时我希望t0启动,但控制台只显示" T1正在工作"并且t0什么都不打印 开始
请让我知道为什么会发生这种行为。
码:
public static void main(String[] args) {
t0 = new Thread(new Run_0());
t1 = new Thread(new Run_1());
t0.start();
t1.start();
}
private static class Run_0 implements Runnable {
public void run() {
// TODO Auto-generated method stub
while (true) {
long startTime = TimeUtils.getTSSec();
synchronized (t1) {
try {
t1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("T0 is writing");
//simulate doing some work
while( (TimeUtils.getTSSec()-startTime) <= 7) {
}
System.out.println("T0 finished writing");
synchronized (t1) {
t1.notify();
}
startTime = TimeUtils.getTSSec();
while( (TimeUtils.getTSSec()-startTime) <= 7) {
}
}
}
}
private static class Run_1 implements Runnable {
public void run() {
// TODO Auto-generated method stub
while(true) {
System.out.println("T1 is working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
答案 0 :(得分:1)
答案 1 :(得分:0)
wait
,notify
和notifyAll
应位于synchronized
块内。你有一个notify
在它之外:
t1.notify(); // <-------
startTime = TimeUtils.getTSSec();
答案 2 :(得分:0)
控制台仅显示“T1正在工作”而t0不打印任何内容,就像它没有启动一样
是的,因为Run_0.run()
中的第一件事是t1.wait();
。这等待有人拨打t1.notify()
或t1.notifyAll()
。我看不到有人打电话给那些人。
当线程在对象上调用wait()
时,它会使线程等待通知对象上的监视器。一个线程不会导致另一个线程等待。它只能等待自己。
重要的是要意识到您正在同步,等待和通知恰好是线程的t1
对象。两个线程之间共享的任何对象都可以工作,因为我们对锁定t0
或t1
线程对象感到困惑,所以应该创建一个最终锁定对象并锁定它:
private final Object lock = new Object();
t0正在编写或执行持续7秒的任务,t1应该等待。
听起来你应该在t1.wait()
课程中拥有Run_1
而不是Run_0
课程。也许Run_0
应该这样做:
// much better way to simulate time passing instead of a spin loop
Thread.sleep(7000);
System.out.println("T0 finished writing");
synchronized (lock) {
lock.notify();
}
然后在Run_1
你会做类似的事情:
synchronized (lock) {
lock.wait();
}
System.out.println("T1 is working");
请注意,我正在使用公共lock
对象。