我创建了一个名为TSchedule的类,它实现了Runnable并扩展了Thread,并将用于对一些Threads(t1,t2,...,t8)进行排序。
每个TSchedule实例都以线程名称,到达时间(休眠时间),依赖项列表(TSchedule数组)和标志传递。
在每个线程完成执行run()方法之后,相应的线程应该打印出“Thread.getName()正在终止”,但是,我似乎无法将所有线程打印出来。
public class TSchedule extends Thread implements Runnable {
private TSchedule[] dependencies;
private int sleepTime;
private boolean done;
public TSchedule (String name, int sleep, TSchedule[] dependencies, boolean done) {
super(name);
sleepTime = sleep;
this.dependencies = dependencies;
this.done = done;
}
public void run() {
try {
sleep(sleepTime);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.err.println(getName() + " arrived at time " + System.currentTimeMillis());
checkDependencies(dependencies);
System.err.println(getName() + " is terminating");
}
public synchronized void checkDependencies(TSchedule[] dependencies) {
if(dependencies != null)
for(int i = 0; i < dependencies.length; i++) {
if(dependencies[i].done != true) {
System.out.println(getName() + " waiting on " + dependencies[i].getName()
+ " time " + System.currentTimeMillis());
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
done = true;
notify();
}
public static void main(String[] args) {
TSchedule t1, t2, t3, t4, t5, t6, t7, t8;
t1 = new TSchedule("t1", 4, null, false);
t2 = new TSchedule("t2", 6, null, false);
t3 = new TSchedule("t3", 7, null, false);
t4 = new TSchedule("t4", 2, new TSchedule[] {t1, t2}, false);
t5 = new TSchedule("t5", 3, new TSchedule[] {t3}, false);
t6 = new TSchedule("t6", 1, new TSchedule[] {t3, t4}, false);
t7 = new TSchedule("t7", 8, new TSchedule[] {t4}, false);
t8 = new TSchedule("t8", 5, new TSchedule[] {t6}, false);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
}
}
以下是我收到的输出:
t4 arrived at time 1398211394620
t6 arrived at time 1398211394620
t5 arrived at time 1398211394621
t4 waiting on t1 time 1398211394620
t5 waiting on t3 time 1398211394621
t6 waiting on t3 time 1398211394621
t1 arrived at time 1398211394622
t1 is terminating
t8 arrived at time 1398211394624
t8 waiting on t6 time 1398211394624
t2 arrived at time 1398211394624
t2 is terminating
t3 arrived at time 1398211394625
t3 is terminating
t7 arrived at time 1398211394627
t7 waiting on t4 time 1398211394627
答案 0 :(得分:0)
问题是wait
和notify
调用应该在不同的对象上进行。
让我们使用t4
进行干预,这取决于t1
和t2
,并且不会终止。
t4 arrived at time 1398211394620
t1 arrived at time 1398211394622
t1 is terminating
t2 arrived at time 1398211394624
t2 is terminating
由于t4
首先运行,它会看到t1
尚未完成,并会调用wait()
这是一种调用this.wait()
的简短方法,即t4.wait()
}
现在t1
运行,因为它没有任何依赖关系,它将直接转到notify()
。问题是,实际上调用的this.notify()
反而是t1.notify()
,而应该调用t4.notify()
。与t2
相同。
因此,没有人醒来t4
,它会停留在那里,等待有人告诉他继续。
查看wait
和notify
:http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html的文档,您将看到需要在同一个锁定对象上进行调用才能获得您期望的行为。
解决问题的一种方法是用if
阻止synchronized
阻止,并更改wait()
来电:
synchronized (dependencies[i]) {
if (dependencies[i].done != true) {
...
dependencies[i].wait();
...
}
}
done = true;
notify();
因此,每个TSchedule等待其依赖关系完成,然后通知自己。