[英]Printing Odd Even number sequentially using two threads
我不明白為什么下面的程序不能在偶數情況下工作。
我得到的輸出In Odd Thread 1
如果我理解程序執行-
轉到t1線程。 條件不滿足。 調用notifyAll,它會被忽略。轉到t2線程,該線程輸出奇數增量並調用wait()。 T2在這種情況下應該開始運行了嗎??
public class OddEvenTest {
static int max = 20;
static int count = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count % 2 == 0 && count < max) {
System.out.println("In even Thread " +count);
count++;
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lock.notifyAll();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count % 2 != 0 && count < max) {
System.out.println("In Odd Thread " +count);
count++;
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lock.notifyAll();
}
}
});
t1.start();
t2.start();
}
}
您不想盲目地在lock
同步的循環中使用wait()
。 相反,請檢查您的wait
條件,例如
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (count < max) {
synchronized (lock) {
if (count % 2 == 0) {
System.out.println("In Even Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (count < max) {
synchronized (lock) {
if (count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
在Java 8+中,您可以使用以下lambda簡化匿名類
Thread t1 = new Thread(() -> {
while (count < max) {
synchronized (lock) {
if (count % 2 == 0) {
System.out.println("In Even Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(() -> {
while (count < max) {
synchronized (lock) {
if (count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
我能想到很多問題
notifyAll已寫在循環外,因此請考慮以下情況:奇數線程正在執行並打印該值,並且即將調用wait,但是偶數線程在奇數線程調用等待之前調用了notify,因此奇數線程將始終處於等待狀態。 因此,您應該在循環內保持notifyAll。
這是您在執行過程中所經歷的。
while循環應繼續執行,直到count小於最大數為止,並且應在while循環內部應用偶數或條件。
等待應該在其他情況下
public class OddEvenTest {
static int max = 20;
static int count = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count < max) {
if(count % 2 == 0 ) {
System.out.println("In even Thread " + count);
count++;
}else{
try {
lock.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
lock.notifyAll();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(count < max) {
if(count % 2 != 0) {
System.out.println("In Odd Thread " + count);
count++;
}else{
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
lock.notifyAll();
}
}
}
});
t1.start();
t2.start();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.