我創建了 5 個執行緒T1,T2..T5。T1設定threadId并計數到2.
隨后,T2應該繼續,因為回圈while(!(Thread.currentThread().getName().equals(threadId.toString()))) 應該失敗。
然而,對于T2,threadId仍然存在1,因此它也在等待。
請讓我知道我在這里缺少什么。
public class Main {
public static void main(String args[])
{
int noOfthreads = 5;
Thread [] t = new Thread[noOfthreads];
for(int i = 0; i<noOfthreads ; i ) {
OddEven oe = new OddEven(15, noOfthreads);
t[i] = new Thread(new Runnable() {
@Override
public void run() {
try {
oe.printNumbers();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
});
}
for(int i = 0; i<noOfthreads ; i ) {
t[i].setName(String.valueOf(i 1));
t[i].start();
System.out.println("started thread " (i 1));
}
for(int i=0; i<noOfthreads; i ) {
try {
t[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class OddEven {
int max ;
int count;
volatile Integer threadId;
int noOfThreads ;
public OddEven(int max, int noOfThreads) {
super();
this.max = max;
this.noOfThreads = noOfThreads;
count = 1 ;
threadId =1;
}
//TODO: Try to pass threadId as a parameeter here
public synchronized void printNumbers() throws InterruptedException
{
while(count <= max)
{
while(!(Thread.currentThread().getName().equals(threadId.toString())))
{
wait();
}
System.out.println("thread " Thread.currentThread().getName() "printed" count) ;
count ;
threadId = (threadId 1)%noOfThreads;
notifyAll();
}
}
}
uj5u.com熱心網友回復:
由于執行緒之間沒有共享狀態,因此彼此看不到更改。每個執行緒都有自己的OddEven實體,因此只有 T1 繼續跳過對 wait() 的呼叫(其 threadId 已經為 1)并終止。T2(和其余的)永遠不會通過 wait() 呼叫,因為沒有人會更改其OddEven實體的 threadId 欄位。
您可以做的第一件事是將 OddEven 的實體化移動到創建執行緒的 for 回圈之外:這樣每個執行緒都將使用相同的OddEven實體。
當你這樣做時,你會注意到前 4 個執行緒將通過他們對 wait() 的第一次呼叫(然后他們將被卡在他們的第二次 wait() 呼叫),而執行緒 5 將繼續卡在它的第一個等待( ) 呼叫:這是因為 threadId 永遠不會達到 5,它走在 [0..4] 范圍內(因為你有 threadId % 5)。要解決此問題,只需從 0 命名您的執行緒,或修復模運算。
當你這樣做時,程式實際上將終止。但是您會注意到您將列印超過最大次數的 5 次(執行緒數)。這是因為 count <= max 條件是在執行緒“增加”之前檢查的。我不知道你想達到/觀察什么,所以我不能就此提供更多建議。
我上面解釋的代碼,所以你可以自己嘗試:
public class Main {
public static void main(String args[])
{
int noOfthreads = 5;
Thread [] t = new Thread[noOfthreads];
OddEven oe = new OddEven(15, noOfthreads);
for(int i = 0; i<noOfthreads ; i ) {
t[i] = new Thread(new Runnable() {
@Override
public void run() {
try {
oe.printNumbers();
} catch (InterruptedException e) {
e.printStackTrace();
};
}
});
}
for(int i = 0; i<noOfthreads ; i ) {
t[i].setName(String.valueOf(i));
t[i].start();
System.out.println("started thread " (i));
}
for(int i=0; i<noOfthreads; i ) {
try {
t[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class OddEven {
int max ;
int count;
volatile Integer threadId;
int noOfThreads ;
public OddEven(int max, int noOfThreads) {
super();
this.max = max;
this.noOfThreads = noOfThreads;
count = 1 ;
threadId = 0;
}
public synchronized void printNumbers() throws InterruptedException
{
while(count <= max)
{
while(!(Thread.currentThread().getName().equals(threadId.toString())))
{
wait();
}
System.out.println("thread " Thread.currentThread().getName() " printed " count) ;
count ;
threadId = (threadId 1)%noOfThreads;
System.out.println("thread " Thread.currentThread().getName() " nextThreadId " threadId) ;
notifyAll();
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/335988.html
