[英]Printing Odd and Even number using 2 threads?
我已經嘗試過此代碼。 但是在打印0之后,它什么也不會打印。 由於某些鎖定,它正在阻塞。
public class EvenOdd implements Runnable {
private Object o = new Object();
private volatile int i = 0;
public void run() {
try {
System.out.println();
if ( Thread.currentThread().getName().equals( "Even")) {
printEven();
} else {
printOdd();
}
} catch ( Exception ee) {
ee.printStackTrace();
}
}
private void printEven() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 == 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
private void printOdd() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 != 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
}
我的TestClass:
EvenOdd x = new EvenOdd();
new Thread(x,"Even").start();
new Thread(x,"Odd").start();
我哪里錯了? 謝謝。
PS:我知道這類問題已經問過很多次了,但我想自己嘗試一下。
我的猜測是你是。
編輯:運行代碼后,OP修復了代碼,它會打印
0
1
如預期的那樣。 有時可能會隨機打印0和0,因為第一次檢查奇數/偶數不同步。
這是一個簡單的僵局:
線程1等待有人通知鎖。 線程2等待有人通知相同的鎖。
由於沒有人去過o.notify();
, 什么都沒發生。
當兩個線程都啟動時, i
為0,因此都先調用printEven()
。 現在,當發生這種情況時,兩個線程將在下一輪調用printOdd()
。
基本概念是當一個線程正在運行時,另一個線程必須等待。 一旦線程打印了值,它就必須等到另一個線程打印出來。 這是通過使用等待/通知機制來實現的。
當奇數線程完成打印值時,它將通知等待線程(偶數線程),並且偶數線程准備就緒,可以運行,但將等待奇數線程釋放鎖定。 現在,奇數線程調用在更衣室對象上等待,以便它釋放鎖並進入等待狀態。 在這一點上,唯一等待鎖對象鎖定的線程是偶數線程並且它正在運行。 此過程將繼續進行。
public class Test {
public static void main(String[] args) {
Object locker = new Object();
Thread t1 = new Thread(new OddWorker(locker));
Thread t2 = new Thread(new EvenWorker(locker));
t1.start();
t2.start();
}
}
class OddWorker implements Runnable {
private Object locker;
private int number = 1, count = 1;
OddWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
locker.notify();
}
}
}
class EvenWorker implements Runnable {
private Object locker;
private int number = 2, count = 1;
EvenWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.