假設有這么一個類:
class ZeroEvenOdd {
??public ZeroEvenOdd(int n) { ... }?? ? ?// 構造函數
? public void zero(printNumber) { ... } ?// 僅打印出 0
? public void even(printNumber) { ... } ?// 僅打印出 偶數
? public void odd(printNumber) { ... } ? // 僅打印出 奇數
}
相同的一個?ZeroEvenOdd?類實例將會傳遞給三個不同的線程:
線程 A 將調用?zero(),它只輸出 0 。
線程 B 將調用?even(),它只輸出偶數。
線程 C 將調用?odd(),它只輸出奇數。
每個線程都有一個?printNumber 方法來輸出一個整數。請修改給出的代碼以輸出整數序列?010203040506... ,其中序列的長度必須為 2n。
?
示例 1:
輸入:n = 2
輸出:"0102"
說明:三條線程異步執行,其中一個調用 zero(),另一個線程調用 even(),最后一個線程調用odd()。正確的輸出為 "0102"。
示例 2:
輸入:n = 5
輸出:"0102030405"
思路:設置三個狀態:-1代表可以打印0,0代表可以打印偶數,1代表可以打印奇數。具體操作請看代碼。
代表狀態的變量要用線程安全的AtomicInteger
class ZeroEvenOdd {private int n;private AtomicInteger done = new AtomicInteger(-1);public ZeroEvenOdd(int n) {this.n = n;}// printNumber.accept(x) outputs "x", where x is an integer.public void zero(IntConsumer printNumber) throws InterruptedException {for(int i=1;i<=n;i++){while(done.get()!=-1)Thread.yield();printNumber.accept(0);done.set(i%2);}}public void even(IntConsumer printNumber) throws InterruptedException {for(int i=2;i<=n;i+=2){while(done.get()!=0)Thread.yield();printNumber.accept(i);done.set(-1);}}public void odd(IntConsumer printNumber) throws InterruptedException {for(int i=1;i<=n;i+=2){while(done.get()!=1)Thread.yield();printNumber.accept(i);done.set(-1);}}
}
?