multithreading print A1B2C3…
In multithreading, one of the classic challenges is ensuring that multiple threads coordinate their execution order to produce a…
Wiki topics:
📚 · Books & Reading
multithreading print A1B2C3…
In multithreading, one of the classic challenges is ensuring that multiple threads coordinate their execution order to produce a predictable output.
Let’s consider a simple but tricky problem:
Write a multithreaded Java program that prints the sequence
A1B2C3...Z26.
- One thread should print letters (
A, B, C, …, Z).- Another thread should print numbers (
1, 2, 3, …, 26).- The threads must run concurrently, but the output must strictly alternate.
- The challenge is to synchronize threads so they print in the required strict alternation.
This is small problem demonstrates big ideas: locks, conditions, semaphores, barriers, and thread communication patterns.
Approach 1: locks, wait and notifyAll
package multithreading;
public class PrintAlternateA1B2C3Approach1 {
private final Object lock = new Object();
private boolean letterTurn = true; // start with letter
public static void main(String[] args) {
PrintAlternateA1B2C3Approach1 printer = new PrintAlternateA1B2C3Approach1();
Thread letterThread = printer.new LetterThread();
Thread numberThread = printer.new NumberThread();
letterThread.start();
numberThread.start();
}
// ---------------- Thread for Letters ----------------
class LetterThread extends Thread {
@Override
public void run() {
printLetters();
}
private void printLetters() {
for (char ch = 'A'; ch <= 'C'; ch++) {
synchronized (lock) {
while (!letterTurn) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.print(ch);
letterTurn = false;
lock.notifyAll();
}
}
}
}
// ---------------- Thread for Numbers ----------------
class NumberThread extends Thread {
@Override
public void run() {
printNumbers();
}
private void printNumbers() {
for (int i = 1; i <= 3; i++) {
synchronized (lock) {
while (letterTurn) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.print(i);
letterTurn = true;
lock.notifyAll();
}
}
}
}
}
Approach 2: ReentrantLock and Condition
package multithreading;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintAlternateA1B2C3ApproachLockAndCondition {
private final Lock lock = new ReentrantLock();
private final Condition letterCondition = lock.newCondition();
private final Condition numberCondition = lock.newCondition();
private boolean letterTurn = true; // start with letter
public static void main(String[] args) {
PrintAlternateA1B2C3ApproachLockAndCondition printer = new PrintAlternateA1B2C3ApproachLockAndCondition();
Thread letterThread = printer.new LetterThread();
Thread numberThread = printer.new NumberThread();
letterThread.start();
numberThread.start();
}
// ---------------- Thread for Letters ----------------
class LetterThread extends Thread {
@Override
public void run() {
printLetters();
}
private void printLetters() {
for (char ch = 'A'; ch <= 'C'; ch++) {
lock.lock();
try {
while (!letterTurn) {
letterCondition.await();
}
System.out.print(ch);
letterTurn = false;
numberCondition.signal(); // wake number thread
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}
}
// ---------------- Thread for Numbers ----------------
class NumberThread extends Thread {
@Override
public void run() {
printNumbers();
}
private void printNumbers() {
for (int i = 1; i <= 3; i++) {
lock.lock();
try {
while (letterTurn) {
numberCondition.await();
}
System.out.print(i);
letterTurn = true;
letterCondition.signal(); // wake letter thread
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}
}
}
Approach 3: Semaphore
package multithreading;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintAlternateA1B2C3ApproachSemaphore {
private final Semaphore letterSemaphore = new Semaphore(1); // letters start first
private final Semaphore numberSemaphore = new Semaphore(0); // numbers wait
public static void main(String[] args) {
PrintAlternateA1B2C3ApproachSemaphore printer = new PrintAlternateA1B2C3ApproachSemaphore();
Thread letterThread = printer.new LetterThread();
Thread numberThread = printer.new NumberThread();
letterThread.start();
numberThread.start();
}
// ---------------- Thread for Letters ----------------
class LetterThread extends Thread {
@Override
public void run() {
printLetters();
}
private void printLetters() {
for (char ch = 'A'; ch <= 'C'; ch++) {
try {
letterSemaphore.acquire(); // wait until it's letter's turn
System.out.print(ch);
numberSemaphore.release(); // give turn to number thread
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
// ---------------- Thread for Numbers ----------------
class NumberThread extends Thread {
@Override
public void run() {
printNumbers();
}
private void printNumbers() {
for (int i = 1; i <= 3; i++) {
try{
numberSemaphore.acquire();
System.out.print(i);
letterSemaphore.release();
}catch (InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
}
}
Approach 4: BlockingQueue
package multithreading;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;
public class PrintAlternateA1B2C3ApproachBlockingQueue {
private final BlockingQueue<Integer> letterQueue = new ArrayBlockingQueue<>(1);
private final BlockingQueue<Integer> numberQueue = new ArrayBlockingQueue<>(1);
public static void main(String[] args) {
PrintAlternateA1B2C3ApproachBlockingQueue printer = new PrintAlternateA1B2C3ApproachBlockingQueue();
Thread letterThread = printer.new LetterThread();
Thread numberThread = printer.new NumberThread();
letterThread.start();
numberThread.start();
}
// ---------------- Thread for Letters ----------------
class LetterThread extends Thread {
@Override
public void run() {
printLetters();
}
private void printLetters() {
for (char ch = 'A'; ch <= 'C'; ch++) {
try {
System.out.print(ch);
numberQueue.put(1);
letterQueue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
// ---------------- Thread for Numbers ----------------
class NumberThread extends Thread {
@Override
public void run() {
printNumbers();
}
private void printNumbers() {
for (int i = 1; i <= 3; i++) {
try{
numberQueue.take();
System.out.print(i);
letterQueue.put(1);
}catch (InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
}
}
Approach 5: Phaser
package multithreading;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Phaser;
public class PrintAlternateA1B2C3ApproachPhaser {
private final Phaser phaser = new Phaser(2); // 2 parties: letter + number
public static void main(String[] args) {
PrintAlternateA1B2C3ApproachPhaser printer = new PrintAlternateA1B2C3ApproachPhaser();
Thread letterThread = printer.new LetterThread();
Thread numberThread = printer.new NumberThread();
letterThread.start();
numberThread.start();
}
// ---------------- Thread for Letters ----------------
class LetterThread extends Thread {
@Override
public void run() {
printLetters();
}
private void printLetters() {
for (char ch = 'A'; ch <= 'C'; ch++) {
System.out.print(ch);
phaser.arriveAndAwaitAdvance(); // wait for nu
}
}
}
// ---------------- Thread for Numbers ----------------
class NumberThread extends Thread {
@Override
public void run() {
printNumbers();
}
private void printNumbers() {
for (int i = 1; i <= 3; i++) {
System.out.print(i);
phaser.arriveAndAwaitAdvance(); // wait for nu
}
}
}
} 메타데이터
- post_id
- 3d80f603a237
- slug
- multithreading-print-a1b2c3-3d80f603a237
- url
- https://medium.com/@sanjayharivilaspal/multithreading-print-a1b2c3-3d80f603a237
- canonical_url
- https://medium.com/@sanjayharivilaspal/multithreading-print-a1b2c3-3d80f603a237
- author_url
- https://medium.com/@sanjayharivilaspal
- status
- ok
- fetched_at
- 2026-07-17 16:58:18