[英]Scheduling Threads and Synchronized Methods
我創建了一個稱為TSchedule的類,該類實現Runnable並擴展Thread,並將用於對少數幾個線程(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
問題在於,應在不同的對象上進行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 ,您將看到需要在同一鎖定對象上進行調用以得到您期望的行為。
解決問題的一種方法是用synchronized
塊包圍if
塊,然后更改wait()
調用:
synchronized (dependencies[i]) {
if (dependencies[i].done != true) {
...
dependencies[i].wait();
...
}
}
done = true;
notify();
因此,每個TSchedule等待其依賴關系完成,然后通知自己。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.