我认为我应该说的第一件事是我不是在寻找解决方案,这是hwk,但是它运行正常,对我来说有什么帮助可以澄清......
我们刚刚在面向对象的编程类中引入了线程,并收到了一个我完成的任务。在我的代码中,我从不调用notifyAll(),但似乎在退出run()之前隐式调用它。我的另一位同学也有同样的问题。我在某个地方读到一个正在等待另一个线程的线程被通知(隐式notifyAll()?)当它正在等待的线程死亡/退出run方法时。这是我的代码(runnable,以及它运行的主要部分)
如果我删除了等待,并用Throwable替换InterruptedException,则代码运行,但不正确,线程在其休眠时间之后出现,然后打印终止消息并按照它们出现的顺序消亡。
我无法发布图片,所以我尽力描述它是如何工作的: 每个线程在分配的时间内休眠,并保存一个Thread数组,该数组保存对必须等待的线程的引用
ex:T1到达2秒取决于T2,T3 T2到达4秒取决于没有人 T3到达6秒取决于没有人 所以... T1到达并且必须等待T2和T3才能终止,T2和T3可以立即终止..
这是到达时间和他们依赖的人:
T1 4秒,没有人 T2 6秒,没有人 T3 7秒,没有人 T4 2秒,T1,T2 T5 3秒,T3 T6 1秒,T3,T4 T7 8秒,T4 T8 5秒,T6
对于可怕的长解释感到抱歉,我不是在寻找解决方案,代码运行正常,我需要澄清一下如果调用wait并且从不调用notify如何运行?
public class TScheduler {
public static void main(String[] args) {
long originTime = System.currentTimeMillis();
// Long.parse.long(args[0]) * 1000
DepThread t1 = new DepThread(originTime , 4000 , new Thread[]{});
Thread T1 = new Thread(t1);
T1.setName("T1");
// Long.parse.long(args[1]) * 1000
DepThread t2 = new DepThread(originTime , 6000 , new Thread[]{});
Thread T2 = new Thread(t2);
T2.setName("T2");
DepThread t3 = new DepThread(originTime , 7000 , new Thread[]{});
Thread T3 = new Thread(t3);
T3.setName("T3");
DepThread t4 = new DepThread(originTime , 2000 , new Thread[]{T1,T2});
Thread T4 = new Thread(t4);
T4.setName("T4");
DepThread t5 = new DepThread(originTime , 3000 , new Thread[]{T3});
Thread T5 = new Thread(t5);
T5.setName("T5");
DepThread t6 = new DepThread(originTime , 1000 , new Thread[]{T3,T4});
Thread T6 = new Thread(t6);
T6.setName("T6");
DepThread t7 = new DepThread(originTime , 8000 , new Thread[]{T4});
Thread T7 = new Thread(t7);
T7.setName("T7");
DepThread t8 = new DepThread(originTime ,5000 , new Thread[]{T6});
Thread T8 = new Thread(t8);
T8.setName("T8");
DepThread t9 = new DepThread(originTime , 500 , new Thread[]{T7});
Thread T9 = new Thread(t9);
T9.setName("T9");
T1.start();
T2.start();
T3.start();
T4.start();
T5.start();
T6.start();
T7.start();
T8.start();
T9.start();
}
}
public class DepThread implements Runnable {
long sleepTime;
Thread[] depThrdArray;
public boolean done = false ;
long baseTime ;
public DepThread( long baseTime , long arrivalTime , Thread[] depThrdArray ){
//super();
this.baseTime = baseTime;
this.sleepTime = arrivalTime;
this.depThrdArray = depThrdArray;
this.done = false;
}
@Override
public void run() {
try {
Thread.sleep(sleepTime);
System.out.println( Thread.currentThread().getName() + " arrived at " + (System.currentTimeMillis() - baseTime));
} catch (InterruptedException e) {
e.printStackTrace();
}
for ( int i = 0 ; i < depThrdArray.length ; i ++){
if ( depThrdArray[i].isAlive()){
synchronized(depThrdArray[i]){
try {
depThrdArray[i].wait();
System.out.println(Thread.currentThread().getName() + " waiting on " + depThrdArray[i].getName()
+ " time " + (System.currentTimeMillis() - this.baseTime));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
this.done = true;
//synchronized (this){
// notifyAll();
//}
System.out.println(Thread.currentThread().getName() + " at time " + ( System.currentTimeMillis() - baseTime) + " terminating");
}
}
答案 0 :(得分:3)
在终止时线程调用notifyAll
以支持join
功能。这在Thread#join
的Javadoc中有记录:
此实现使用以
this.wait
为条件的this.isAlive
次调用循环。当线程终止时,将调用this.notifyAll
方法。建议应用程序不要在wait
个实例上使用notify
,notifyAll
或Thread
。
基本上有两个结论:
join
。wait
,请不要将Thread实例用作监视器。