1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 class FizzBuzz { private enum State { FIZZ, BUZZ, FIZZBUZZ, NUM } private final Object lock = new Object (); private final int n; private State state; public FizzBuzz (int n) { this .n = n; this .state = State.NUM; } public void fizz (Runnable printFizz) throws InterruptedException { for (int i = 3 ; i <= n; i += 3 ) { if (i % 5 == 0 ) { continue ; } synchronized (lock) { while (state != State.FIZZ) { lock.wait(); } printFizz.run(); switchState(i); lock.notifyAll(); } } } private void switchState (int i) { int nextNum = i + 1 ; if (nextNum % 3 == 0 && nextNum % 5 != 0 ) { state = State.FIZZ; } else if (nextNum % 5 == 0 && nextNum % 3 != 0 ) { state = State.BUZZ; } else if (nextNum % 3 == 0 && nextNum % 5 == 0 ) { state = State.FIZZBUZZ; } else { state = State.NUM; } } public void buzz (Runnable printBuzz) throws InterruptedException { for (int i = 5 ; i <= n; i += 5 ) { if (i % 3 == 0 ) { continue ; } synchronized (lock) { while (state != State.BUZZ) { lock.wait(); } printBuzz.run(); switchState(i); lock.notifyAll(); } } } public void fizzbuzz (Runnable printFizzBuzz) throws InterruptedException { for (int i = 15 ; i <= n; i += 15 ) { synchronized (lock) { while (state != State.FIZZBUZZ) { lock.wait(); } printFizzBuzz.run(); switchState(i); lock.notifyAll(); } } } public void number (IntConsumer printNumber) throws InterruptedException { for (int i = 1 ; i <= n; i++) { if (i % 3 == 0 || i % 5 == 0 ) { continue ; } synchronized (lock) { while (state != State.NUM) { lock.wait(); } printNumber.accept(i); switchState(i); lock.notifyAll(); } } } }
References 1195. Fizz Buzz Multithreaded