Knowledge Guide
HomeConcurrencyConcurrency Problems

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:

The twist here is to print this sequence concurrently using four separate threads, adding complexity in terms of synchronization.

Step-by-step Algorithm

  1. Initialize

    • Start with the first number.
    • Set up synchronization tools (locks, conditions, etc.).
  2. 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.
  3. 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".
  4. Thread C (FizzBuzz Printer)

    • A combination of A & B:
      • Wait until the current number is divisible by both 3 and 5.
      • Print "fizzbuzz".
  5. 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.
  6. Wrap-up

    • When the current number exceeds n, all threads stop.

Algorithm Walkthrough

Let's take a small value of n, say n = 15, and see how threads interact:

  1. Initialization

    • current_number starts 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.
  2. Threads Execution

    • Thread A (Fizz Printer): Waits for current_number to be divisible by 3 but not by 5. When it's its turn, it acquires the lock, prints "Fizz", increments current_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_number to 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.
  3. Synchronization in Action

    • When current_number is 1, only Thread D can print because it's neither divisible by 3 nor 5. Threads A, B, and C are waiting.
    • When current_number is 3, Thread A wakes up as the condition is satisfied, prints "Fizz", and then increments current_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.
  4. Wrap-up

    • When current_number exceeds n, no more printing occurs, and all threads will eventually stop after completing their last check.

Key Points

Here are various implementations:

Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
java
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.

🪜 Hint ladder (no spoilers)

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.
🎨 Explain the approach visually

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.
🔍 Review my solution

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.
🔁 Drill the pattern

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.

📝 My notes