Problem 7 FizzBuzz Multithreading Problem
Overview
The FizzBuzz problem has been around for a long time as a classic programming challenge. In this multithreaded variant, we are tasked to print a series from 1 up to a number n with some rules:
- Print "fizz" for numbers divisible by 3.
- Print "buzz" for numbers divisible by 5.
- Print "fizzbuzz" for numbers divisible by both 3 and 5.
- Print the number itself otherwise.
The twist here is to print this sequence concurrently using four separate threads, adding complexity in terms of synchronization.
Step-by-step Algorithm
-
Initialize
- Start with the first number.
- Set up synchronization tools (locks, conditions, etc.).
-
Thread A (Fizz Printer)
- While the current number is less than or equal to n
- Acquire the lock.
- Wait until the current number is divisible by 3 but not by 5.
- Print "fizz".
- Increment the current number.
- Notify all other threads.
- Release the lock.
- While the current number is less than or equal to n
-
Thread B (Buzz Printer)
- Similar to Thread A, but the condition changes:
- Wait until the current number is divisible by 5 but not by 3.
- Print "buzz".
- Similar to Thread A, but the condition changes:
-
Thread C (FizzBuzz Printer)
- A combination of A & B:
- Wait until the current number is divisible by both 3 and 5.
- Print "fizzbuzz".
- A combination of A & B:
-
Thread D (Number Printer)
- Waits for numbers that are neither divisible by 3 nor 5:
- Wait until the current number is not divisible by either 3 or 5.
- Print the current number.
- Waits for numbers that are neither divisible by 3 nor 5:
-
Wrap-up
- When the current number exceeds
n, all threads stop.
- When the current number exceeds
Algorithm Walkthrough
Let's take a small value of n, say n = 15, and see how threads interact:
-
Initialization
current_numberstarts at 1.- A lock is initialized to enforce mutual exclusion.
- Condition variables for each thread's condition are set up to control the flow of execution.
-
Threads Execution
- Thread A (Fizz Printer): Waits for
current_numberto be divisible by 3 but not by 5. When it's its turn, it acquires the lock, prints "Fizz", incrementscurrent_number, notifies other threads, and releases the lock. - Thread B (Buzz Printer): Does the same as Thread A, but for numbers divisible by 5 and not by 3.
- Thread C (FizzBuzz Printer): Waits for
current_numberto be divisible by both 3 and 5. It follows the same synchronization pattern. - Thread D (Number Printer): Waits for numbers that are divisible by neither 3 nor 5 and prints the number itself.
- Thread A (Fizz Printer): Waits for
-
Synchronization in Action
- When
current_numberis 1, only Thread D can print because it's neither divisible by 3 nor 5. Threads A, B, and C are waiting. - When
current_numberis 3, Thread A wakes up as the condition is satisfied, prints "Fizz", and then incrementscurrent_number. - At
current_number= 5, Thread B wakes up to print "Buzz". - This pattern continues, with each thread waiting for its correct turn based on the value of
current_number.
- When
-
Wrap-up
- When
current_numberexceedsn, no more printing occurs, and all threads will eventually stop after completing their last check.
- When
Key Points
- Locks are used to prevent more than one thread from entering a critical section of code at the same time.
- Condition Variables allow threads to wait for a certain condition to become true. In this case, the conditions are based on the divisibility of
current_number. - Each thread is responsible for waiting for its specific condition to be true before it can execute its print function.
- Threads notify each other after printing so the next correct thread can take its turn.
- Proper synchronization ensures the sequence of numbers is printed according to the FizzBuzz rules, even though the work is divided across multiple threads.
Here are various implementations:






import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Solution {
private final int n; // Total number of sequence
private int current; // Current number being processed
private final Lock lock = new ReentrantLock(); // Lock for synchronization
private final Condition cond = lock.newCondition(); // Condition variable for coordination between threads
public Solution(int n) {
this.n = n;
this.current = 1;
}
public void fizz() throws InterruptedException {
while (true) {
lock.lock();
try {
while (current <= n && !(current % 3 == 0 && current % 5 != 0)) {
cond.await();
}
if (current > n) break;
System.out.println("fizz");
current++;
cond.signalAll();
} finally {
lock.unlock();
}
}
}
public void buzz() throws InterruptedException {
while (true) {
lock.lock();
try {
while (current <= n && !(current % 5 == 0 && current % 3 != 0)) {
cond.await();
}
if (current > n) break;
System.out.println("buzz");
current++;
cond.signalAll();
} finally {
lock.unlock();
}
}
}
public void Solution() throws InterruptedException {
while (true) {
lock.lock();
try {
while (current <= n && !(current % 15 == 0)) {
cond.await();
}
if (current > n) break;
System.out.println("Solution");
current++;
cond.signalAll();
} finally {
lock.unlock();
}
}
}
public void number() throws InterruptedException {
while (true) {
lock.lock();
try {
while (current <= n && !(current % 3 != 0 && current % 5 != 0)) {
cond.await();
}
if (current > n) break;
System.out.println(current);
current++;
cond.signalAll();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
int n = 10;
Solution fb = new Solution(n);
Thread t1 = new Thread(() -> {
try {
fb.fizz();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread t2 = new Thread(() -> {
try {
fb.buzz();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread t3 = new Thread(() -> {
try {
fb.Solution();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread t4 = new Thread(() -> {
try {
fb.number();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
t1.start();
t2.start();
t3.start();
t4.start();
}
}
🤖 Don't fully get this? Learn it with Claude
Stuck on Problem 7 FizzBuzz Multithreading Problem? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Problem 7 FizzBuzz Multithreading Problem** (Concurrency). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Problem 7 FizzBuzz Multithreading Problem** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Problem 7 FizzBuzz Multithreading Problem**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Problem 7 FizzBuzz Multithreading Problem**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.