我需要兩個線程來寫入一個共享的整數數組。兩個線程都需要寫入該數組的所有元素。每個線程將寫入1或7,結果應該像171717171(或71717171)。爲此,我在位置0處寫入第一個Thread1,然後等待。線程2現在寫入位置0和1,通知線程1,並等待。 Thread1在位置1和2處寫入,通知Thread2並等待等等。使用下面的代碼,我可以得到正確的輸出,但是當與JPF一起運行時,它會發現死鎖。它變得非常令人沮喪,因爲我找不到它有什麼問題。任何意見,將不勝感激。線程調度 - 共享數組
import java.util.logging.Level;
import java.util.logging.Logger;
public class WriterThreadManager {
private int[] array = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private Thread thread7;
private Thread thread1;
public static void main(String[] args) {
WriterThreadManager mng = new WriterThreadManager();
mng.exec();
}
public WriterThreadManager() {
thread7 = new Thread(new WriterRunnable(this, 7));
thread1 = new Thread(new WriterRunnable(this, 1));
}
public void overwriteArray(int pos, int num) {
array[pos] = num;
printArray();
}
private void printArray() {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
System.out.println("");
}
public synchronized void stopThread() {
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(WriterThreadManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public synchronized void wakeUpThread() {
notifyAll();
}
private void exec() {
thread7.start();
thread1.start();
}
public int length() {
return array.length;
}
}
public class WriterRunnable implements Runnable {
private WriterThreadManager mng;
private int numberToWrite;
private static boolean flag = true;
@Override
public void run() {
int counter = 0;
int j = 0;
//first thread to get in should write only at
//position 0 and then wait.
synchronized (mng) {
if (flag) {
flag = false;
mng.overwriteArray(0, numberToWrite);
j = 1;
waitForOtherThread();
}
}
for (int i = j; i < mng.length(); i++) {
mng.overwriteArray(i, numberToWrite);
counter++;
if (i == mng.length() - 1) {
mng.wakeUpThread();
break;
}
if (counter == 2) {
waitForOtherThread();
counter = 0;
}
}
}
private void waitForOtherThread() {
mng.wakeUpThread();
mng.stopThread();
}
public WriterRunnable(WriterThreadManager ar, int num) {
mng = ar;
numberToWrite = num;
}
}
PS:在執行的例子:
1000000000
7000000000
7700000000
7100000000
7110000000
7170000000
7177000000
7171000000
7171100000
7171700000
7171770000
7171710000
7171711000
7171717000
7171717700
7171717100
7171717110
7171717170
7171717177
7171717171
從JPF錯誤快照如下:
thread java.lang.Thread:{id:1,name:Thread-1,status:WAITING,priority:5,lockCount:1,suspendCount:0}
waiting on: [email protected]
call stack:
at java.lang.Object.wait(Object.java)
at WriterThreadManager.stopThread(WriterThreadManager.java:43)
at WriterRunnable.waitForOtherThread(WriterRunnable.java:53)
at WriterRunnable.run(WriterRunnable.java:45)
thread java.lang.Thread:{id:2,name:Thread-2,status:WAITING,priority:5,lockCount:1,suspendCount:0}
waiting on: [email protected]
call stack:
at java.lang.Object.wait(Object.java)
at WriterThreadManager.stopThread(WriterThreadManager.java:43)
at WriterRunnable.waitForOtherThread(WriterRunnable.java:53)
at WriterRunnable.run(WriterRunnable.java:45)
是否需要嚴格依次寫入?這似乎是使用Semaphore的經典案例。 – Perception
那麼,你在3個不同的對象上同步(管理器和兩個可運行的)。你不會在循環內部等待()以檢查條件。並且對數組的每次訪問都不同步。絕對使用更高級別的抽象(例如信號量)來同步你的線程。 –
由於這是作業,OP可能會受限於他可以使用的內容。 –