Java 调度线程和同步方法
我已经创建了一个名为TSchedule的类,它实现了Runnable并扩展了Thread,将用于对少数线程t1、t2、…、t8排序 TSSchedule的每个实例都以线程名称、到达时间睡眠时间、依赖项列表、TSSchedule数组和标志的形式传递 在每个线程执行完run方法之后,各自的线程都应该打印出thread.getName正在终止,但是,我似乎无法让所有线程都打印出来Java 调度线程和同步方法,java,multithreading,Java,Multithreading,我已经创建了一个名为TSchedule的类,它实现了Runnable并扩展了Thread,将用于对少数线程t1、t2、…、t8排序 TSSchedule的每个实例都以线程名称、到达时间睡眠时间、依赖项列表、TSSchedule数组和标志的形式传递 在每个线程执行完run方法之后,各自的线程都应该打印出thread.getName正在终止,但是,我似乎无法让所有线程都打印出来 public class TSchedule extends Thread implements Runnable {
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();
}
}
问题是wait和notify调用应该在不同的对象上进行
让我们使用t4进行一次试运行,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运行,因为它没有任何依赖项,所以它将直接去通知。问题是它实际上调用了this.notify,而this.notify又是t1.notify,它应该调用t4.notify。t2也是这样
因此,没有人叫醒t4,它就呆在那里,等待有人告诉他继续
检查文档中的wait和notify:您将看到需要对同一个lock对象进行调用,以获得预期的行为
解决问题的一种方法是用同步块包围if块并更改等待呼叫:
因此,每个TSchedule都会等待其依赖项完成,然后通知自己。wait做什么?wait会将当前线程置于等待状态,释放它在TSchedule对象上的锁,这允许其他线程实例输入checkDependencies。为什么要在同一类中实现runnable和extend Thread!因此,我可以通过调用Supername为每个线程实例命名,正如@MingtaoZhang所说,如果类扩展了线程,它就不需要再次实现Runnable。那么我怎么才能通知呢?请解释为什么每个依赖项都调用wait和notify?谢谢。有了我的解决方案,家长们正在明确地等待他们的依赖关系。同时,每个没有依赖项的TSSchedule将正常结束并通知。此通知将由显式等待的父级接收,依此类推。通过试运行帮助您理解这个概念。我已经编辑了我的解决方案,将notify添加到末尾,以使其更清晰。
t4 arrived at time 1398211394620
t1 arrived at time 1398211394622
t1 is terminating
t2 arrived at time 1398211394624
t2 is terminating
synchronized (dependencies[i]) {
if (dependencies[i].done != true) {
...
dependencies[i].wait();
...
}
}
done = true;
notify();