編寫一個可以從 1 到 n 輸出代表這個數字的字符串的程序,但是:
如果這個數字可以被 3 整除,輸出 "fizz"。
如果這個數字可以被 5 整除,輸出?"buzz"。
如果這個數字可以同時被 3 和 5 整除,輸出 "fizzbuzz"。
例如,當?n = 15,輸出:?1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz。
假設有這么一個類:
class FizzBuzz {
??public FizzBuzz(int n) { ... }?? ? ? ? ? ? ? // constructor
? public void fizz(printFizz) { ... } ? ? ? ? ?// only output "fizz"
? public void buzz(printBuzz) { ... } ? ? ? ? ?// only output "buzz"
? public void fizzbuzz(printFizzBuzz) { ... } ?// only output "fizzbuzz"
? public void number(printNumber) { ... } ? ? ?// only output the numbers
}
請你實現一個有四個線程的多線程版??FizzBuzz,?同一個?FizzBuzz?實例會被如下四個線程使用:
線程A將調用?fizz()?來判斷是否能被 3 整除,如果可以,則輸出?fizz。
線程B將調用?buzz()?來判斷是否能被 5 整除,如果可以,則輸出?buzz。
線程C將調用?fizzbuzz()?來判斷是否同時能被 3 和 5 整除,如果可以,則輸出?fizzbuzz。
線程D將調用?number()?來實現輸出既不能被 3 整除也不能被 5 整除的數字。
?
題意:四個方法分別打印四種數字,但是要按順序執行。
思路:number代表當前需要打印(執行)的數字,其他線程判斷不是自己的均不可執行。當前數字執行后+1即可。
import java.util.concurrent.Semaphore;class FizzBuzz {private int n;private AtomicInteger number = new AtomicInteger(1);//當前應該打印的數字public FizzBuzz(int n) {this.n = n;}// printFizz.run() outputs "fizz".public void fizz(Runnable printFizz) throws InterruptedException {for (int i = 1; i <= n; i++) {if(i % 3 == 0 && i % 5 != 0){while(number.get()!=i)Thread.yield();printFizz.run();number.set(number.get()+1);}}}// printBuzz.run() outputs "buzz".public void buzz(Runnable printBuzz) throws InterruptedException {for (int i = 0; i <= n; i++) {if(i % 3 != 0 && i % 5 == 0){while(number.get()!=i)Thread.yield();printBuzz.run();number.set(number.get()+1);}}}// printFizzBuzz.run() outputs "fizzbuzz".public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {for (int i = 1; i <= n; i++) {if(i % 3 == 0 && i % 5 == 0){while(number.get()!=i)Thread.yield();printFizzBuzz.run();number.set(number.get()+1);}}}// printNumber.accept(x) outputs "x", where x is an integer.public void number(IntConsumer printNumber) throws InterruptedException {for (int i = 1; i <= n; i++) {if (i % 3 != 0 && i % 5 != 0) {while(number.get()!=i)Thread.yield();printNumber.accept(i);number.set(number.get()+1);}}}
}
?