Java 多线程交替打印 50 种实现方法

  1. 基础同步机制实现
    1.1 synchronized + wait/notify 机制
    1.1.1 使用 this 作为锁对象
    public class AlternatePrintSynchronizedThis {
    private int count = 1;
    private final int max = 100;

    public synchronized void printOdd() {
    while (count <= max) {
    if (count % 2 != 0) {
    System.out.println(Thread.currentThread().getName() + ": " + count++);
    notify();
    } else {
    try {
    wait();
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    }
    }
    }
    }

    public synchronized void printEven() {
    while (count <= max) {
    if (count % 2 == 0) {
    System.out.println(Thread.currentThread().getName() + ": " + count++);
    notify();
    } else {
    try {
    wait();
    } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    }
    }
    }
    }

    public static void main(String[] args) {
    AlternatePrintSynchronizedThis printer = new AlternatePrintSynchronizedThis();
    new Thread(printer::printOdd, “Thread-1”).start();
    new Thread(printer::printEven, “Thread-2”).start();
    }
    }

1.1.2 使用独立的锁对象
public class AlternatePrintSynchronizedObject {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printOdd() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSynchronizedObject printer = new AlternatePrintSynchronizedObject();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.3 使用类对象作为锁
public class AlternatePrintSynchronizedClass {
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        synchronized (AlternatePrintSynchronizedClass.class) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                AlternatePrintSynchronizedClass.class.notify();
            } else {
                try {
                    AlternatePrintSynchronizedClass.class.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void printEven() {
    while (count <= max) {
        synchronized (AlternatePrintSynchronizedClass.class) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                AlternatePrintSynchronizedClass.class.notify();
            } else {
                try {
                    AlternatePrintSynchronizedClass.class.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintSynchronizedClass::printOdd, "Thread-1").start();
    new Thread(AlternatePrintSynchronizedClass::printEven, "Thread-2").start();
}

}

1.1.4 使用 wait/notifyAll 组合
public class AlternatePrintSynchronizedNotifyAll {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printOdd() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notifyAll();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notifyAll();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSynchronizedNotifyAll printer = new AlternatePrintSynchronizedNotifyAll();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.5 基于状态变量的实现
public class AlternatePrintSynchronizedState {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        synchronized (lock) {
            while (!isOddTurn) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            isOddTurn = false;
            lock.notify();
        }
    }
}

public void printEven() {
    while (count <= max) {
        synchronized (lock) {
            while (isOddTurn) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            isOddTurn = true;
            lock.notify();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSynchronizedState printer = new AlternatePrintSynchronizedState();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.6 使用循环等待条件
public class AlternatePrintSynchronizedLoop {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printOdd() {
    synchronized (lock) {
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public void printEven() {
    synchronized (lock) {
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSynchronizedLoop printer = new AlternatePrintSynchronizedLoop();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.7 超时等待机制
public class AlternatePrintSynchronizedTimeout {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printOdd() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait(1000); // 等待1秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait(1000); // 等待1秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSynchronizedTimeout printer = new AlternatePrintSynchronizedTimeout();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.8 多线程轮流打印(3 个线程)
public class AlternatePrintThreeThreads {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printA() {
    while (count <= max) {
        synchronized (lock) {
            while (count % 3 != 1) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("Thread-A: " + count++);
            lock.notifyAll();
        }
    }
}

public void printB() {
    while (count <= max) {
        synchronized (lock) {
            while (count % 3 != 2) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("Thread-B: " + count++);
            lock.notifyAll();
        }
    }
}

public void printC() {
    while (count <= max) {
        synchronized (lock) {
            while (count % 3 != 0) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("Thread-C: " + count++);
            lock.notifyAll();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintThreeThreads printer = new AlternatePrintThreeThreads();
    new Thread(printer::printA, "Thread-A").start();
    new Thread(printer::printB, "Thread-B").start();
    new Thread(printer::printC, "Thread-C").start();
}

}

1.1.9 使用双重检查锁定
public class AlternatePrintDoubleCheck {
private volatile int count = 1;
private final int max = 100;
private final Object lock = new Object();

public void printOdd() {
    while (count <= max) {
        if (count % 2 != 0) {
            synchronized (lock) {
                if (count % 2 != 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                }
            }
        } else {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        if (count % 2 == 0) {
            synchronized (lock) {
                if (count % 2 == 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                }
            }
        } else {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintDoubleCheck printer = new AlternatePrintDoubleCheck();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

1.1.10 使用静态锁对象
public class AlternatePrintStaticLock {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

public static void printOdd() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void printEven() {
    while (count <= max) {
        synchronized (lock) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                lock.notify();
            } else {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintStaticLock::printOdd, "Thread-1").start();
    new Thread(AlternatePrintStaticLock::printEven, "Thread-2").start();
}

}

1.2 volatile 变量配合忙等待
1.2.1 简单的 volatile 标志位实现
public class AlternatePrintVolatileSimple {
private static volatile boolean isOddTurn = true;
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while (!isOddTurn) {
            Thread.yield(); // 让出CPU
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn = false;
    }
}

public static void printEven() {
    while (count <= max) {
        while (isOddTurn) {
            Thread.yield(); // 让出CPU
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn = true;
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintVolatileSimple::printOdd, "Thread-1").start();
    new Thread(AlternatePrintVolatileSimple::printEven, "Thread-2").start();
}

}

1.2.2 双重 volatile 变量控制
public class AlternatePrintVolatileDouble {
private static volatile boolean oddReady = true;
private static volatile boolean evenReady = false;
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while (!oddReady) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        oddReady = false;
        evenReady = true;
    }
}

public static void printEven() {
    while (count <= max) {
        while (!evenReady) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        evenReady = false;
        oddReady = true;
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintVolatileDouble::printOdd, "Thread-1").start();
    new Thread(AlternatePrintVolatileDouble::printEven, "Thread-2").start();
}

}

1.2.3 使用 AtomicBoolean
import java.util.concurrent.atomic.AtomicBoolean;

public class AlternatePrintAtomicBoolean {
private static AtomicBoolean isOddTurn = new AtomicBoolean(true);
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while (!isOddTurn.get()) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn.set(false);
    }
}

public static void printEven() {
    while (count <= max) {
        while (isOddTurn.get()) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn.set(true);
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintAtomicBoolean::printOdd, "Thread-1").start();
    new Thread(AlternatePrintAtomicBoolean::printEven, "Thread-2").start();
}

}

1.2.4 基于 AtomicInteger 的实现
import java.util.concurrent.atomic.AtomicInteger;

public class AlternatePrintAtomicInteger {
private static AtomicInteger count = new AtomicInteger(1);
private static final int max = 100;
private static volatile boolean isOddTurn = true;

public static void printOdd() {
    while (count.get() <= max) {
        while (!isOddTurn) {
            Thread.yield();
        }
        int current = count.getAndIncrement();
        System.out.println(Thread.currentThread().getName() + ": " + current);
        isOddTurn = false;
    }
}

public static void printEven() {
    while (count.get() <= max) {
        while (isOddTurn) {
            Thread.yield();
        }
        int current = count.getAndIncrement();
        System.out.println(Thread.currentThread().getName() + ": " + current);
        isOddTurn = true;
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintAtomicInteger::printOdd, "Thread-1").start();
    new Thread(AlternatePrintAtomicInteger::printEven, "Thread-2").start();
}

}

1.2.5 使用 volatile 数组控制
public class AlternatePrintVolatileArray {
private static volatile int[] flags = new int[2];
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while (flags[0] != 1) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        flags[0] = 0;
        flags[1] = 1;
    }
}

public static void printEven() {
    while (count <= max) {
        while (flags[1] != 1) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        flags[1] = 0;
        flags[0] = 1;
    }
}

public static void main(String[] args) {
    flags[0] = 1; // 初始时奇数线程可以执行
    new Thread(AlternatePrintVolatileArray::printOdd, "Thread-1").start();
    new Thread(AlternatePrintVolatileArray::printEven, "Thread-2").start();
}

}

1.2.6 基于位运算的 volatile 实现
public class AlternatePrintBitwiseVolatile {
private static volatile int turn = 0; // 0表示奇数,1表示偶数
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while ((turn & 1) != 0) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        turn ^= 1; // 切换标志
    }
}

public static void printEven() {
    while (count <= max) {
        while ((turn & 1) == 0) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        turn ^= 1; // 切换标志
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintBitwiseVolatile::printOdd, "Thread-1").start();
    new Thread(AlternatePrintBitwiseVolatile::printEven, "Thread-2").start();
}

}

1.2.7 带超时的 volatile 实现
public class AlternatePrintVolatileTimeout {
private static volatile boolean isOddTurn = true;
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        long startTime = System.currentTimeMillis();
        while (!isOddTurn) {
            if (System.currentTimeMillis() - startTime > 1000) { // 超时1秒
                System.out.println("Timeout occurred in odd thread");
                break;
            }
            Thread.yield();
        }
        if (count > max) break;
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn = false;
    }
}

public static void printEven() {
    while (count <= max) {
        long startTime = System.currentTimeMillis();
        while (isOddTurn) {
            if (System.currentTimeMillis() - startTime > 1000) { // 超时1秒
                System.out.println("Timeout occurred in even thread");
                break;
            }
            Thread.yield();
        }
        if (count > max) break;
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        isOddTurn = true;
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintVolatileTimeout::printOdd, "Thread-1").start();
    new Thread(AlternatePrintVolatileTimeout::printEven, "Thread-2").start();
}

}

1.2.8 使用 LongAdder 优化
import java.util.concurrent.atomic.LongAdder;

public class AlternatePrintLongAdder {
private static LongAdder count = new LongAdder();
private static final int max = 100;
private static volatile boolean isOddTurn = true;

public static void printOdd() {
    count.increment();
    while (count.longValue() <= max) {
        while (!isOddTurn) {
            Thread.yield();
        }
        long current = count.longValue();
        if (current % 2 != 0) {
            System.out.println(Thread.currentThread().getName() + ": " + current);
            count.increment();
            isOddTurn = false;
        }
    }
}

public static void printEven() {
    while (count.longValue() <= max) {
        while (isOddTurn) {
            Thread.yield();
        }
        long current = count.longValue();
        if (current % 2 == 0) {
            System.out.println(Thread.currentThread().getName() + ": " + current);
            count.increment();
            isOddTurn = true;
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintLongAdder::printOdd, "Thread-1").start();
    new Thread(AlternatePrintLongAdder::printEven, "Thread-2").start();
}

}

1.2.9 基于数组的多线程控制
public class AlternatePrintVolatileArrayMulti {
private static volatile int[] threadTurns = new int[3]; // 3个线程
private static int count = 1;
private static final int max = 100;

public static void printA() {
    threadTurns[0] = 1; // 初始时A线程可以执行
    while (count <= max) {
        while (threadTurns[0] != 1) {
            Thread.yield();
        }
        System.out.println("Thread-A: " + count++);
        threadTurns[0] = 0;
        threadTurns[1] = 1; // 轮到B线程
    }
}

public static void printB() {
    while (count <= max) {
        while (threadTurns[1] != 1) {
            Thread.yield();
        }
        System.out.println("Thread-B: " + count++);
        threadTurns[1] = 0;
        threadTurns[2] = 1; // 轮到C线程
    }
}

public static void printC() {
    while (count <= max) {
        while (threadTurns[2] != 1) {
            Thread.yield();
        }
        System.out.println("Thread-C: " + count++);
        threadTurns[2] = 0;
        threadTurns[0] = 1; // 轮到A线程
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintVolatileArrayMulti::printA, "Thread-A").start();
    new Thread(AlternatePrintVolatileArrayMulti::printB, "Thread-B").start();
    new Thread(AlternatePrintVolatileArrayMulti::printC, "Thread-C").start();
}

}

1.2.10 使用 AtomicReference 控制状态
import java.util.concurrent.atomic.AtomicReference;

public class AlternatePrintAtomicReference {
private static AtomicReference currentTurn = new AtomicReference<>(“odd”);
private static int count = 1;
private static final int max = 100;

public static void printOdd() {
    while (count <= max) {
        while (!currentTurn.get().equals("odd")) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        currentTurn.set("even");
    }
}

public static void printEven() {
    while (count <= max) {
        while (!currentTurn.get().equals("even")) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + ": " + count++);
        currentTurn.set("odd");
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintAtomicReference::printOdd, "Thread-1").start();
    new Thread(AlternatePrintAtomicReference::printEven, "Thread-2").start();
}

}

  1. 高级并发工具实现
    2.1 ReentrantLock 与 Condition
    2.1.1 基本 ReentrantLock 实现
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockBasic {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();

public void printOdd() {
    while (count <= max) {
        lock.lock();
        try {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
        } finally {
            lock.unlock();
        }
    }
}

public void printEven() {
    while (count <= max) {
        lock.lock();
        try {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
        } finally {
            lock.unlock();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintReentrantLockBasic printer = new AlternatePrintReentrantLockBasic();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.2 使用多个 Condition 对象
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockConditions {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private final Condition oddCondition = lock.newCondition();
private final Condition evenCondition = lock.newCondition();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        lock.lock();
        try {
            while (!isOddTurn) {
                oddCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            isOddTurn = false;
            evenCondition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
}

public void printEven() {
    while (count <= max) {
        lock.lock();
        try {
            while (isOddTurn) {
                evenCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            isOddTurn = true;
            oddCondition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintReentrantLockConditions printer = new AlternatePrintReentrantLockConditions();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.3 基于数字条件的 Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockNumberCondition {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private final Condition oddCondition = lock.newCondition();
private final Condition evenCondition = lock.newCondition();

public void printOdd() {
    while (count <= max) {
        lock.lock();
        try {
            while (count % 2 == 0) {
                oddCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenCondition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    evenCondition.signalAll(); // 确保最后一个线程能退出
}

public void printEven() {
    while (count <= max) {
        lock.lock();
        try {
            while (count % 2 != 0) {
                evenCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddCondition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    oddCondition.signalAll(); // 确保最后一个线程能退出
}

public static void main(String[] args) {
    AlternatePrintReentrantLockNumberCondition printer = new AlternatePrintReentrantLockNumberCondition();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.4 公平锁与非公平锁对比
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintFairnessComparison {
private int count = 1;
private final int max = 100;
private final Lock fairLock = new ReentrantLock(true); // 公平锁
private final Lock unfairLock = new ReentrantLock(false); // 非公平锁
private volatile boolean isFair = true;

public void printWithFairLock() {
    while (count <= max) {
        fairLock.lock();
        try {
            if (isFair) {
                System.out.println("Fair Lock - " + Thread.currentThread().getName() + ": " + count++);
                isFair = false;
            }
        } finally {
            fairLock.unlock();
        }
    }
}

public void printWithUnfairLock() {
    while (count <= max) {
        unfairLock.lock();
        try {
            if (!isFair) {
                System.out.println("Unfair Lock - " + Thread.currentThread().getName() + ": " + count++);
                isFair = true;
            }
        } finally {
            unfairLock.unlock();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintFairnessComparison printer = new AlternatePrintFairnessComparison();
    new Thread(printer::printWithFairLock, "Thread-1").start();
    new Thread(printer::printWithUnfairLock, "Thread-2").start();
}

}

2.1.5 使用 tryLock () 方法
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintTryLock {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        if (lock.tryLock()) { // 尝试获取锁
            try {
                if (isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = false;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        if (lock.tryLock()) { // 尝试获取锁
            try {
                if (!isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = true;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintTryLock printer = new AlternatePrintTryLock();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.6 带超时的 tryLock 实现
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import java.util.concurrent.TimeUnit;

public class AlternatePrintTryLockTimeout {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        try {
            if (lock.tryLock(1, TimeUnit.SECONDS)) { // 等待1秒
                try {
                    if (isOddTurn) {
                        System.out.println(Thread.currentThread().getName() + ": " + count++);
                        isOddTurn = false;
                    }
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println("Timeout occurred in odd thread");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public void printEven() {
    while (count <= max) {
        try {
            if (lock.tryLock(1, TimeUnit.SECONDS)) { // 等待1秒
                try {
                    if (!isOddTurn) {
                        System.out.println(Thread.currentThread().getName() + ": " + count++);
                        isOddTurn = true;
                    }
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println("Timeout occurred in even thread");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintTryLockTimeout printer = new AlternatePrintTryLockTimeout();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.7 使用可中断的 lock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintInterruptibleLock {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        try {
            lock.lockInterruptibly(); // 可中断的加锁
            try {
                if (isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = false;
                }
            } finally {
                lock.unlock();
            }
        } catch (InterruptedException e) {
            System.out.println("Odd thread was interrupted");
            Thread.currentThread().interrupt();
            break;
        }
    }
}

public void printEven() {
    while (count <= max) {
        try {
            lock.lockInterruptibly(); // 可中断的加锁
            try {
                if (!isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = true;
                }
            } finally {
                lock.unlock();
            }
        } catch (InterruptedException e) {
            System.out.println("Even thread was interrupted");
            Thread.currentThread().interrupt();
            break;
        }
    }
}

public static void main(String[] args) {
    AlternatePrintInterruptibleLock printer = new AlternatePrintInterruptibleLock();
    Thread t1 = new Thread(printer::printOdd, "Thread-1");
    Thread t2 = new Thread(printer::printEven, "Thread-2");
    t1.start();
    t2.start();

    try {
        Thread.sleep(2000); // 2秒后中断线程
        t1.interrupt();
        t2.interrupt();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

}

2.1.8 基于 ReentrantLock 的多线程轮询
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockMultiThread {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private final Condition[] conditions = new Condition[3];

public AlternatePrintReentrantLockMultiThread() {
    for (int i = 0; i < 3; i++) {
        conditions[i] = lock.newCondition();
    }
}

public void print(int threadId) {
    while (count <= max) {
        lock.lock();
        try {
            while (count % 3 != threadId) {
                conditions[threadId].await();
            }
            System.out.println("Thread-" + threadId + ": " + count++);
            conditions[(threadId + 1) % 3].signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    // 唤醒所有线程以便退出
    for (Condition condition : conditions) {
        condition.signalAll();
    }
}

public static void main(String[] args) {
    AlternatePrintReentrantLockMultiThread printer = new AlternatePrintReentrantLockMultiThread();
    new Thread(() -> printer.print(0), "Thread-0").start();
    new Thread(() -> printer.print(1), "Thread-1").start();
    new Thread(() -> printer.print(2), "Thread-2").start();
}

}

2.1.9 使用 ReentrantLock 配合 Atomic 变量
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockAtomic {
private AtomicInteger count = new AtomicInteger(1);
private final int max = 100;
private final Lock lock = new ReentrantLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count.get() <= max) {
        lock.lock();
        try {
            if (isOddTurn) {
                System.out.println(Thread.currentThread().getName() + ": " + count.getAndIncrement());
                isOddTurn = false;
            }
        } finally {
            lock.unlock();
        }
    }
}

public void printEven() {
    while (count.get() <= max) {
        lock.lock();
        try {
            if (!isOddTurn) {
                System.out.println(Thread.currentThread().getName() + ": " + count.getAndIncrement());
                isOddTurn = true;
            }
        } finally {
            lock.unlock();
        }
    }
}

public static void main(String[] args) {
    AlternatePrintReentrantLockAtomic printer = new AlternatePrintReentrantLockAtomic();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.1.10 ReentrantLock 与 volatile 组合优化
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintReentrantLockVolatileOptimized {
private volatile int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    while (count <= max) {
        if (isOddTurn) {
            lock.lock();
            try {
                if (isOddTurn) { // 双重检查
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = false;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public void printEven() {
    while (count <= max) {
        if (!isOddTurn) {
            lock.lock();
            try {
                if (!isOddTurn) { // 双重检查
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = true;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintReentrantLockVolatileOptimized printer = new AlternatePrintReentrantLockVolatileOptimized();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.2 CountDownLatch
2.2.1 基本 CountDownLatch 实现
import java.util.concurrent.CountDownLatch;

public class AlternatePrintCountDownLatchBasic {
private int count = 1;
private final int max = 100;
private final CountDownLatch latch = new CountDownLatch(1);

public void printOdd() {
    try {
        for (int i = 0; i < max / 2 + max % 2; i++) {
            latch.await(); // 等待
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            latch.countDown(); // 计数减一
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        for (int i = 0; i < max / 2; i++) {
            latch.await(); // 等待
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            latch.countDown(); // 计数减一
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCountDownLatchBasic printer = new AlternatePrintCountDownLatchBasic();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
    printer.latch.countDown(); // 开始
}

}

2.2.2 使用两个 CountDownLatch
import java.util.concurrent.CountDownLatch;

public class AlternatePrintTwoCountDownLatches {
private int count = 1;
private final int max = 100;
private final CountDownLatch oddLatch = new CountDownLatch(1);
private final CountDownLatch evenLatch = new CountDownLatch(0);

public void printOdd() {
    try {
        while (count <= max) {
            oddLatch.await(); // 等待
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenLatch.countDown(); // 唤醒偶数线程
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            evenLatch.await(); // 等待
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddLatch.countDown(); // 唤醒奇数线程
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintTwoCountDownLatches printer = new AlternatePrintTwoCountDownLatches();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
    // 初始时奇数线程先执行
    printer.oddLatch.countDown();
}

}

2.2.3 三线程轮询打印
import java.util.concurrent.CountDownLatch;

public class AlternatePrintThreeThreadsCountDownLatch {
private int count = 1;
private final int max = 100;
private final CountDownLatch latchA = new CountDownLatch(1);
private final CountDownLatch latchB = new CountDownLatch(0);
private final CountDownLatch latchC = new CountDownLatch(0);

public void printA() {
    try {
        while (count <= max) {
            latchA.await();
            if (count > max) break;
            System.out.println("Thread-A: " + count++);
            latchB.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printB() {
    try {
        while (count <= max) {
            latchB.await();
            if (count > max) break;
            System.out.println("Thread-B: " + count++);
            latchC.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printC() {
    try {
        while (count <= max) {
            latchC.await();
            if (count > max) break;
            System.out.println("Thread-C: " + count++);
            latchA.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintThreeThreadsCountDownLatch printer = new AlternatePrintThreeThreadsCountDownLatch();
    new Thread(printer::printA, "Thread-A").start();
    new Thread(printer::printB, "Thread-B").start();
    new Thread(printer::printC, "Thread-C").start();
    printer.latchA.countDown(); // 初始时A线程先执行
}

}

2.2.4 使用 CyclicBarrier 配合 CountDownLatch
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintMixedBarrierLatch {
private int count = 1;
private final int max = 100;
private final CountDownLatch startLatch = new CountDownLatch(1);
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void printOdd() {
    try {
        startLatch.await(); // 等待开始信号
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await(); // 等待另一个线程
            } else {
                barrier.await(); // 等待并跳过
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        startLatch.await(); // 等待开始信号
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await(); // 等待另一个线程
            } else {
                barrier.await(); // 等待并跳过
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintMixedBarrierLatch printer = new AlternatePrintMixedBarrierLatch();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
    printer.startLatch.countDown(); // 开始执行
}

}

2.2.5 使用多个 CountDownLatch 实现轮询
import java.util.concurrent.CountDownLatch;

public class AlternatePrintMultiLatchRoundRobin {
private int count = 1;
private final int max = 100;
private final CountDownLatch[] latches = new CountDownLatch[4];

public AlternatePrintMultiLatchRoundRobin() {
    for (int i = 0; i < 4; i++) {
        latches[i] = new CountDownLatch(i == 0 ? 1 : 0);
    }
}

public void print(int threadId) {
    try {
        while (count <= max) {
            latches[threadId].await();
            if (count > max) break;
            System.out.println("Thread-" + threadId + ": " + count++);
            latches[(threadId + 1) % 4].countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintMultiLatchRoundRobin printer = new AlternatePrintMultiLatchRoundRobin();
    for (int i = 0; i < 4; i++) {
        final int id = i;
        new Thread(() -> printer.print(id), "Thread-" + id).start();
    }
}

}

2.2.6 使用超时的 await 方法
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class AlternatePrintCountDownLatchTimeout {
private int count = 1;
private final int max = 100;
private final CountDownLatch oddLatch = new CountDownLatch(1);
private final CountDownLatch evenLatch = new CountDownLatch(0);

public void printOdd() {
    try {
        while (count <= max) {
            if (oddLatch.await(1, TimeUnit.SECONDS)) { // 等待1秒
                if (count > max) break;
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                evenLatch.countDown();
            } else {
                System.out.println("Odd thread timeout");
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            if (evenLatch.await(1, TimeUnit.SECONDS)) { // 等待1秒
                if (count > max) break;
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                oddLatch.countDown();
            } else {
                System.out.println("Even thread timeout");
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCountDownLatchTimeout printer = new AlternatePrintCountDownLatchTimeout();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.2.7 使用辅助线程控制
import java.util.concurrent.CountDownLatch;

public class AlternatePrintLatchWithControlThread {
private int count = 1;
private final int max = 100;
private final CountDownLatch oddLatch = new CountDownLatch(1);
private final CountDownLatch evenLatch = new CountDownLatch(0);

public void printOdd() {
    try {
        while (count <= max) {
            oddLatch.await();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenLatch.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            evenLatch.await();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddLatch.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintLatchWithControlThread printer = new AlternatePrintLatchWithControlThread();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();

    // 控制线程
    new Thread(() -> {
        try {
            printer.oddLatch.countDown(); // 开始
            while (printer.count <= printer.max) {
                Thread.sleep(10); // 控制节奏
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }).start();
}

}

2.2.8 使用 CyclicBarrier 重置
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCountDownLatchWithBarrierReset {
private int count = 1;
private final int max = 100;
private final CountDownLatch startLatch = new CountDownLatch(1);
private final CyclicBarrier barrier = new CyclicBarrier(2, () -> {
if (count > max) {
// 重置所有latch以便线程退出
startLatch.countDown();
}
});

public void printOdd() {
    try {
        startLatch.await();
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        startLatch.await();
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCountDownLatchWithBarrierReset printer = new AlternatePrintCountDownLatchWithBarrierReset();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
    printer.startLatch.countDown(); // 开始
}

}

2.2.9 使用 Future 配合 CountDownLatch
import java.util.concurrent.*;

public class AlternatePrintFutureWithLatch {
private int count = 1;
private final int max = 100;
private final CountDownLatch oddLatch = new CountDownLatch(1);
private final CountDownLatch evenLatch = new CountDownLatch(0);

public void printOdd() {
    try {
        while (count <= max) {
            oddLatch.await();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenLatch.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            evenLatch.await();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddLatch.countDown();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintFutureWithLatch printer = new AlternatePrintFutureWithLatch();
    ExecutorService executor = Executors.newFixedThreadPool(2);

    Future<?> f1 = executor.submit(printer::printOdd);
    Future<?> f2 = executor.submit(printer::printEven);

    printer.oddLatch.countDown(); // 开始

    try {
        f1.get();
        f2.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        executor.shutdown();
    }
}

}

2.2.10 使用 Phaser 配合 CountDownLatch
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Phaser;

public class AlternatePrintPhaserWithLatch {
private int count = 1;
private final int max = 100;
private final CountDownLatch startLatch = new CountDownLatch(1);
private final Phaser phaser = new Phaser(2);

public void printOdd() {
    try {
        startLatch.await();
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
            phaser.arriveAndAwaitAdvance();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        startLatch.await();
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
            phaser.arriveAndAwaitAdvance();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintPhaserWithLatch printer = new AlternatePrintPhaserWithLatch();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
    printer.startLatch.countDown(); // 开始
}

}

2.3 CyclicBarrier
2.3.1 基本 CyclicBarrier 实现
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierBasic {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);
private volatile boolean isOddTurn = true;

public void printOdd() {
    try {
        while (count <= max) {
            if (isOddTurn) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                isOddTurn = false;
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            barrier.await();
            if (count <= max) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                isOddTurn = true;
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierBasic printer = new AlternatePrintCyclicBarrierBasic();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.3.2 使用 Runnable barrierAction
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierAction {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2, this::incrementCount);

private void incrementCount() {
    if (count < max) {
        count++;
    }
}

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count);
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierAction printer = new AlternatePrintCyclicBarrierAction();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.3.3 三线程循环打印
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintThreeThreadsCyclicBarrier {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(3);

public void printA() {
    try {
        while (count <= max) {
            if (count % 3 == 1) {
                System.out.println("Thread-A: " + count);
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printB() {
    try {
        while (count <= max) {
            if (count % 3 == 2) {
                System.out.println("Thread-B: " + count);
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printC() {
    try {
        while (count <= max) {
            if (count % 3 == 0) {
                System.out.println("Thread-C: " + count);
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintThreeThreadsCyclicBarrier printer = new AlternatePrintThreeThreadsCyclicBarrier();
    new Thread(printer::printA, "Thread-A").start();
    new Thread(printer::printB, "Thread-B").start();
    new Thread(printer::printC, "Thread-C").start();
}

}

2.3.4 使用 parties 参数动态调整
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierDynamicParties {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);
private volatile int currentParties = 2;

public void printOdd() {
    try {
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await();
            } else {
                barrier.await(currentParties); // 使用动态parties
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await();
            } else {
                barrier.await(currentParties); // 使用动态parties
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierDynamicParties printer = new AlternatePrintCyclicBarrierDynamicParties();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.3.5 使用超时的 await 方法
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class AlternatePrintCyclicBarrierTimeout {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            barrier.await(1, TimeUnit.SECONDS); // 等待1秒
        }
    } catch (InterruptedException | BrokenBarrierException | TimeoutException e) {
        Thread.currentThread().interrupt();
        System.out.println("Timeout occurred: " + e.getMessage());
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierTimeout printer = new AlternatePrintCyclicBarrierTimeout();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.3.6 使用 reset () 方法
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierReset {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void printOdd() {
    try {
        while (count <= max) {
            if (count % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await();
            } else {
                barrier.reset(); // 重置barrier
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                barrier.await();
            } else {
                barrier.reset(); // 重置barrier
            }
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierReset printer = new AlternatePrintCyclicBarrierReset();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.3.7 使用 isBroken () 方法
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierBroken {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            if (count > max/2) {
                // 打破barrier
                if (Thread.currentThread().getName().equals("Thread-1")) {
                    ((Thread) Thread.currentThread()).interrupt();
                }
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        if (barrier.isBroken()) {
            System.out.println("Barrier is broken, exiting...");
            barrier.reset(); // 重置barrier
        }
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierBroken printer = new AlternatePrintCyclicBarrierBroken();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.3.8 使用 getNumberWaiting () 方法
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierWaiting {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            System.out.println("Number of threads waiting: " + barrier.getNumberWaiting());
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierWaiting printer = new AlternatePrintCyclicBarrierWaiting();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.3.9 使用 getParties () 方法
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class AlternatePrintCyclicBarrierParties {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            System.out.println("Parties: " + barrier.getParties());
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierParties printer = new AlternatePrintCyclicBarrierParties();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.3.10 结合 ReentrantLock 使用
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintCyclicBarrierWithLock {
private int count = 1;
private final int max = 100;
private final CyclicBarrier barrier = new CyclicBarrier(2);
private final Lock lock = new ReentrantLock();

public void print() {
    try {
        while (count <= max) {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            } finally {
                lock.unlock();
            }
            barrier.await();
        }
    } catch (InterruptedException | BrokenBarrierException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintCyclicBarrierWithLock printer = new AlternatePrintCyclicBarrierWithLock();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.4 其他并发工具
2.4.1 Semaphore 信号量
import java.util.concurrent.Semaphore;

public class AlternatePrintSemaphore {
private int count = 1;
private final int max = 100;
private final Semaphore oddSemaphore = new Semaphore(1);
private final Semaphore evenSemaphore = new Semaphore(0);

public void printOdd() {
    try {
        while (count <= max) {
            oddSemaphore.acquire();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenSemaphore.release();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            evenSemaphore.acquire();
            if (count > max) break;
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddSemaphore.release();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintSemaphore printer = new AlternatePrintSemaphore();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.2 Exchanger 交换器
import java.util.concurrent.Exchanger;

public class AlternatePrintExchanger {
private int count = 1;
private final int max = 100;
private final Exchanger exchanger = new Exchanger<>();
private volatile String currentTurn = “odd”;

public void printOdd() {
    try {
        while (count <= max) {
            if (currentTurn.equals("odd")) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                currentTurn = exchanger.exchange("even");
            } else {
                currentTurn = exchanger.exchange(currentTurn);
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public void printEven() {
    try {
        while (count <= max) {
            if (currentTurn.equals("even")) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
                currentTurn = exchanger.exchange("odd");
            } else {
                currentTurn = exchanger.exchange(currentTurn);
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    AlternatePrintExchanger printer = new AlternatePrintExchanger();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.3 Phaser 分阶段同步器
import java.util.concurrent.Phaser;

public class AlternatePrintPhaser {
private int count = 1;
private final int max = 100;
private final Phaser phaser = new Phaser(2);

public void print() {
    try {
        while (count <= max) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            phaser.arriveAndAwaitAdvance();
        }
    } finally {
        phaser.arriveAndDeregister();
    }
}

public static void main(String[] args) {
    AlternatePrintPhaser printer = new AlternatePrintPhaser();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.4.4 使用 Phaser 实现多阶段控制
import java.util.concurrent.Phaser;

public class AlternatePrintPhaserMultiStage {
private int count = 1;
private final int max = 100;
private final Phaser phaser = new Phaser(2);

public void print() {
    try {
        while (count <= max) {
            if (count % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ": " + count);
                phaser.arriveAndAwaitAdvance(); // 偶数线程等待
                count++;
            } else {
                System.out.println(Thread.currentThread().getName() + ": " + count);
                count++;
                phaser.arriveAndAwaitAdvance(); // 奇数线程等待
            }
        }
    } finally {
        phaser.arriveAndDeregister();
    }
}

public static void main(String[] args) {
    AlternatePrintPhaserMultiStage printer = new AlternatePrintPhaserMultiStage();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.4.5 使用 Phaser 的 onAdvance 方法
import java.util.concurrent.Phaser;

public class AlternatePrintPhaserAdvance {
private int count = 1;
private final int max = 100;
private final Phaser phaser = new Phaser(2) {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
if (count < max) {
count++;
return false;
}
return true; // 终止Phaser
}
};

public void print() {
    try {
        while (!phaser.isTerminated()) {
            System.out.println(Thread.currentThread().getName() + ": " + count);
            phaser.arriveAndAwaitAdvance();
        }
    } finally {
        phaser.arriveAndDeregister();
    }
}

public static void main(String[] args) {
    AlternatePrintPhaserAdvance printer = new AlternatePrintPhaserAdvance();
    new Thread(printer::print, "Thread-1").start();
    new Thread(printer::print, "Thread-2").start();
}

}

2.4.6 使用 StampedLock
import java.util.concurrent.locks.StampedLock;

public class AlternatePrintStampedLock {
private int count = 1;
private final int max = 100;
private final StampedLock lock = new StampedLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    long stamp = 0;
    try {
        while (count <= max) {
            stamp = lock.writeLock();
            try {
                if (isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = false;
                }
            } finally {
                lock.unlockWrite(stamp);
            }
        }
    } finally {
        if (stamp != 0) {
            lock.unlockWrite(stamp);
        }
    }
}

public void printEven() {
    long stamp = 0;
    try {
        while (count <= max) {
            stamp = lock.writeLock();
            try {
                if (!isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = true;
                }
            } finally {
                lock.unlockWrite(stamp);
            }
        }
    } finally {
        if (stamp != 0) {
            lock.unlockWrite(stamp);
        }
    }
}

public static void main(String[] args) {
    AlternatePrintStampedLock printer = new AlternatePrintStampedLock();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.7 使用 StampedLock 的乐观读
import java.util.concurrent.locks.StampedLock;

public class AlternatePrintStampedLockOptimistic {
private int count = 1;
private final int max = 100;
private final StampedLock lock = new StampedLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    long stamp;
    try {
        while (count <= max) {
            stamp = lock.tryOptimisticRead();
            if (isOddTurn) {
                if (lock.validate(stamp)) { // 验证乐观读
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    stamp = lock.writeLock();
                    try {
                        isOddTurn = false;
                    } finally {
                        lock.unlockWrite(stamp);
                    }
                }
            }
        }
    } finally {
        // 不需要释放乐观读锁
    }
}

public void printEven() {
    long stamp;
    try {
        while (count <= max) {
            stamp = lock.tryOptimisticRead();
            if (!isOddTurn) {
                if (lock.validate(stamp)) { // 验证乐观读
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    stamp = lock.writeLock();
                    try {
                        isOddTurn = true;
                    } finally {
                        lock.unlockWrite(stamp);
                    }
                }
            }
        }
    } finally {
        // 不需要释放乐观读锁
    }
}

public static void main(String[] args) {
    AlternatePrintStampedLockOptimistic printer = new AlternatePrintStampedLockOptimistic();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.8 使用 ReentrantReadWriteLock
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class AlternatePrintReadWriteLock {
private int count = 1;
private final int max = 100;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    try {
        while (count <= max) {
            lock.writeLock().lock();
            try {
                if (isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = false;
                }
            } finally {
                lock.writeLock().unlock();
            }
        }
    } finally {
        // 确保锁被释放
    }
}

public void printEven() {
    try {
        while (count <= max) {
            lock.writeLock().lock();
            try {
                if (!isOddTurn) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    isOddTurn = true;
                }
            } finally {
                lock.writeLock().unlock();
            }
        }
    } finally {
        // 确保锁被释放
    }
}

public static void main(String[] args) {
    AlternatePrintReadWriteLock printer = new AlternatePrintReadWriteLock();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.9 使用 ReentrantReadWriteLock 的读锁优化
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class AlternatePrintReadWriteLockOptimized {
private int count = 1;
private final int max = 100;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private volatile boolean isOddTurn = true;

public void printOdd() {
    try {
        while (count <= max) {
            lock.readLock().lock();
            try {
                if (isOddTurn) {
                    lock.readLock().unlock();
                    lock.writeLock().lock();
                    try {
                        if (isOddTurn) { // 双重检查
                            System.out.println(Thread.currentThread().getName() + ": " + count++);
                            isOddTurn = false;
                        }
                    } finally {
                        lock.writeLock().unlock();
                    }
                }
            } finally {
                if (lock.getReadHoldCount() > 0) {
                    lock.readLock().unlock();
                }
            }
        }
    } finally {
        // 确保锁被释放
    }
}

public void printEven() {
    try {
        while (count <= max) {
            lock.readLock().lock();
            try {
                if (!isOddTurn) {
                    lock.readLock().unlock();
                    lock.writeLock().lock();
                    try {
                        if (!isOddTurn) { // 双重检查
                            System.out.println(Thread.currentThread().getName() + ": " + count++);
                            isOddTurn = true;
                        }
                    } finally {
                        lock.writeLock().unlock();
                    }
                }
            } finally {
                if (lock.getReadHoldCount() > 0) {
                    lock.readLock().unlock();
                }
            }
        }
    } finally {
        // 确保锁被释放
    }
}

public static void main(String[] args) {
    AlternatePrintReadWriteLockOptimized printer = new AlternatePrintReadWriteLockOptimized();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

2.4.10 使用 AtomicStampedReference
import java.util.concurrent.atomic.AtomicStampedReference;

public class AlternatePrintAtomicStampedReference {
private int count = 1;
private final int max = 100;
private final AtomicStampedReference turn = new AtomicStampedReference<>(true, 0);

public void printOdd() {
    int[] stamp = new int[1];
    while (count <= max) {
        boolean currentTurn = turn.get(stamp);
        if (currentTurn) {
            if (turn.compareAndSet(currentTurn, false, stamp[0], stamp[0] + 1)) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
        }
    }
}

public void printEven() {
    int[] stamp = new int[1];
    while (count <= max) {
        boolean currentTurn = turn.get(stamp);
        if (!currentTurn) {
            if (turn.compareAndSet(currentTurn, true, stamp[0], stamp[0] + 1)) {
                System.out.println(Thread.currentThread().getName() + ": " + count++);
            }
        }
    }
}

public static void main(String[] args) {
    AlternatePrintAtomicStampedReference printer = new AlternatePrintAtomicStampedReference();
    new Thread(printer::printOdd, "Thread-1").start();
    new Thread(printer::printEven, "Thread-2").start();
}

}

  1. 线程池与框架实现
    3.1 ExecutorService
    3.1.1 使用 FixedThreadPool
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintFixedThreadPool {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private final Condition oddCondition = lock.newCondition();
private final Condition evenCondition = lock.newCondition();

public void printOdd() {
    try {
        lock.lock();
        while (count <= max) {
            while (count % 2 == 0) {
                oddCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenCondition.signal();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
}

public void printEven() {
    try {
        lock.lock();
        while (count <= max) {
            while (count % 2 != 0) {
                evenCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddCondition.signal();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
}

public static void main(String[] args) {
    AlternatePrintFixedThreadPool printer = new AlternatePrintFixedThreadPool();
    ExecutorService executor = Executors.newFixedThreadPool(2);
    executor.execute(printer::printOdd);
    executor.execute(printer::printEven);
    executor.shutdown();
}

}

3.1.2 使用 CachedThreadPool
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintCachedThreadPool {
private int count = 1;
private final int max = 100;
private final Lock lock = new ReentrantLock();
private final Condition oddCondition = lock.newCondition();
private final Condition evenCondition = lock.newCondition();

public void printOdd() {
    try {
        lock.lock();
        while (count <= max) {
            while (count % 2 == 0) {
                oddCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            evenCondition.signal();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
}

public void printEven() {
    try {
        lock.lock();
        while (count <= max) {
            while (count % 2 != 0) {
                evenCondition.await();
            }
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            oddCondition.signal();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
}

public static void main(String[] args) {
    AlternatePrintCachedThreadPool printer = new AlternatePrintCachedThreadPool();
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(printer::printOdd);
    executor.execute(printer::printEven);
    executor.shutdown();
}

}

3.1.3 使用 SingleThreadExecutor
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AlternatePrintSingleThreadExecutor {
private int count = 1;
private final int max = 100;
private volatile boolean isOddTurn = true;

public void print() {
    while (count <= max) {
        if ((Thread.currentThread().getName().contains("pool-1-thread-1") && isOddTurn) ||
            (Thread.currentThread().getName().contains("pool-1-thread-2") && !isOddTurn)) {
            System.out.println(Thread.currentThread().getName() + ": " + count++);
            isOddTurn = !isOddTurn;
        }
    }
}

public static void main(String[] args) {
    AlternatePrintSingleThreadExecutor printer = new AlternatePrintSingleThreadExecutor();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(printer::print);
    executor.execute(printer::print);
    executor.shutdown();
}

}

3.1.4 使用 Callable 和 Future
import java.util.concurrent.*;

public class AlternatePrintCallableFuture {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public Future<?> printOdd() {
    return CompletableFuture.runAsync(() -> {
        synchronized (lock) {
            while (count <= max) {
                if (count % 2 != 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    });
}

public Future<?> printEven() {
    return CompletableFuture.runAsync(() -> {
        synchronized (lock) {
            while (count <= max) {
                if (count % 2 == 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    });
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    AlternatePrintCallableFuture printer = new AlternatePrintCallableFuture();
    Future<?> f1 = printer.printOdd();
    Future<?> f2 = printer.printEven();
    f1.get();
    f2.get();
}

}

3.1.5 使用 ScheduledExecutorService
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class AlternatePrintScheduledExecutor {
private int count = 1;
private final int max = 100;
private volatile boolean isOddTurn = true;

public void print() {
    if (count > max) return;
    if (isOddTurn) {
        System.out.println("Thread-1: " + count++);
        isOddTurn = false;
    } else {
        System.out.println("Thread-2: " + count++);
        isOddTurn = true;
    }
}

public static void main(String[] args) {
    AlternatePrintScheduledExecutor printer = new AlternatePrintScheduledExecutor();
    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
    scheduler.scheduleAtFixedRate(printer::print, 0, 10, TimeUnit.MILLISECONDS);
    scheduler.scheduleAtFixedRate(printer::print, 5, 10, TimeUnit.MILLISECONDS);

    try {
        Thread.sleep(2000); // 运行2秒
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        scheduler.shutdown();
    }
}

}

3.1.6 使用 ScheduledExecutorService 的 schedule 方法
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

public class AlternatePrintScheduledFixedRate {
private int count = 1;
private final int max = 100;
private final AtomicInteger turn = new AtomicInteger(0);

public void print() {
    if (count > max) return;
    int currentTurn = turn.getAndIncrement() % 2;
    if (currentTurn == 0) {
        System.out.println("Thread-1: " + count++);
    } else {
        System.out.println("Thread-2: " + count++);
    }
}

public static void main(String[] args) {
    AlternatePrintScheduledFixedRate printer = new AlternatePrintScheduledFixedRate();
    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
    scheduler.scheduleAtFixedRate(printer::print, 0, 10, TimeUnit.MILLISECONDS);
    scheduler.scheduleAtFixedRate(printer::print, 5, 10, TimeUnit.MILLISECONDS);

    try {
        Thread.sleep(2000); // 运行2秒
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        scheduler.shutdown();
    }
}

}

3.1.7 使用 CompletionService
import java.util.concurrent.*;

public class AlternatePrintCompletionService {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public Future<?> submitPrintOdd(ExecutorService executor) {
    return executor.submit(() -> {
        synchronized (lock) {
            while (count <= max) {
                if (count % 2 != 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    lock.wait();
                }
            }
        }
    });
}

public Future<?> submitPrintEven(ExecutorService executor) {
    return executor.submit(() -> {
        synchronized (lock) {
            while (count <= max) {
                if (count % 2 == 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    lock.wait();
                }
            }
        }
    });
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    AlternatePrintCompletionService printer = new AlternatePrintCompletionService();
    ExecutorService executor = Executors.newFixedThreadPool(2);
    CompletionService<Void> completionService = new ExecutorCompletionService<>(executor);

    completionService.submit(printer::submitPrintOdd, null);
    completionService.submit(printer::submitPrintEven, null);

    for (int i = 0; i < 2; i++) {
        completionService.take().get();
    }

    executor.shutdown();
}

}

3.1.8 使用 invokeAll 方法
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class AlternatePrintInvokeAll {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public Future<?> createPrintTask(boolean isOdd) {
    return new FutureTask<>(() -> {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    lock.wait();
                }
            }
        }
        return null;
    });
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    AlternatePrintInvokeAll printer = new AlternatePrintInvokeAll();
    ExecutorService executor = Executors.newFixedThreadPool(2);

    List<Future<?>> futures = new ArrayList<>();
    futures.add(printer.createPrintTask(true));
    futures.add(printer.createPrintTask(false));

    executor.invokeAll(futures);
    executor.shutdown();
}

}

3.1.9 使用 invokeAny 方法
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class AlternatePrintInvokeAny {
private int count = 1;
private final int max = 100;
private final Object lock = new Object();

public Callable<String> createPrintCallable(boolean isOdd) {
    return () -> {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    lock.wait();
                }
            }
        }
        return "Completed";
    };
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    AlternatePrintInvokeAny printer = new AlternatePrintInvokeAny();
    ExecutorService executor = Executors.newFixedThreadPool(2);

    List<Callable<String>> callables = new ArrayList<>();
    callables.add(printer.createPrintCallable(true));
    callables.add(printer.createPrintCallable(false));

    String result = executor.invokeAny(callables);
    System.out.println("Result: " + result);
    executor.shutdown();
}

}

3.1.10 使用 ForkJoinPool
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintForkJoin {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintTask extends RecursiveAction {
    private final boolean isOdd;

    public PrintTask(boolean isOdd) {
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintTask(true));
    pool.invoke(new PrintTask(false));
    pool.shutdown();
}

}

3.2 Fork/Join 框架
3.2.1 使用 RecursiveAction
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintRecursiveAction {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintAction extends RecursiveAction {
    private final boolean isOdd;

    public PrintAction(boolean isOdd) {
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintAction(true));
    pool.invoke(new PrintAction(false));
    pool.shutdown();
}

}

3.2.2 使用 RecursiveTask
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class AlternatePrintRecursiveTask {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintTask extends RecursiveTask<String> {
    private final boolean isOdd;

    public PrintTask(boolean isOdd) {
        this.isOdd = isOdd;
    }

    @Override
    protected String compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
        return "Completed";
    }
}

public static void main(String[] args) throws Exception {
    ForkJoinPool pool = new ForkJoinPool(2);
    String result1 = pool.invoke(new PrintTask(true));
    String result2 = pool.invoke(new PrintTask(false));
    System.out.println("Results: " + result1 + ", " + result2);
    pool.shutdown();
}

}

3.2.3 分治策略实现
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintDivideAndConquer {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintTask extends RecursiveAction {
    private final int start;
    private final int end;
    private final boolean isOdd;

    public PrintTask(int start, int end, boolean isOdd) {
        this.start = start;
        this.end = end;
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        if (start <= end) {
            synchronized (lock) {
                while (count <= max) {
                    if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                        System.out.println(Thread.currentThread().getName() + ": " + count++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintTask(1, max, true));
    pool.invoke(new PrintTask(1, max, false));
    pool.shutdown();
}

}

3.2.4 使用工作窃取机制
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintWorkStealing {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintStealingTask extends RecursiveAction {
    private final int threshold;
    private final boolean isOdd;

    public PrintStealingTask(int threshold, boolean isOdd) {
        this.threshold = threshold;
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        if (threshold > 0) {
            synchronized (lock) {
                while (count <= max) {
                    if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                        System.out.println(Thread.currentThread().getName() + ": " + count++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                }
            }
        } else {
            // 拆分任务
            invokeAll(new PrintStealingTask(threshold + 1, isOdd),
                    new PrintStealingTask(threshold + 1, isOdd));
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool();
    pool.invoke(new PrintStealingTask(0, true));
    pool.invoke(new PrintStealingTask(0, false));
    pool.shutdown();
}

}

3.2.5 使用 ForkJoinPool.commonPool ()
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintCommonPool {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class CommonPrintTask extends RecursiveAction {
    private final boolean isOdd;

    public CommonPrintTask(boolean isOdd) {
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool.commonPool().invoke(new CommonPrintTask(true));
    ForkJoinPool.commonPool().invoke(new CommonPrintTask(false));
}

}

3.2.6 使用 ForkJoinWorkerThreadFactory
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintWorkerThreadFactory {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class CustomThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
    private final String prefix;

    public CustomThreadFactory(String prefix) {
        this.prefix = prefix;
    }

    @Override
    public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
        ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
        thread.setName(prefix + "-" + thread.getPoolIndex());
        return thread;
    }
}

static class PrintTask extends RecursiveAction {
    private final boolean isOdd;

    public PrintTask(boolean isOdd) {
        this.isOdd = isOdd;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2,
            new CustomThreadFactory("PrintThread"),
            null,
            false);
    pool.invoke(new PrintTask(true));
    pool.invoke(new PrintTask(false));
    pool.shutdown();
}

}

3.2.7 使用 getSurplusQueuedTaskCount ()
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintSurplusTaskCount {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintStatusTask extends RecursiveAction {
    private final boolean isOdd;
    private final ForkJoinPool pool;

    public PrintStatusTask(boolean isOdd, ForkJoinPool pool) {
        this.isOdd = isOdd;
        this.pool = pool;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    System.out.println("Surplus tasks: " + pool.getSurplusQueuedTaskCount());
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintStatusTask(true, pool));
    pool.invoke(new PrintStatusTask(false, pool));
    pool.shutdown();
}

}

3.2.8 使用 getPoolSize ()
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintPoolSize {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintWithPoolSize extends RecursiveAction {
    private final boolean isOdd;
    private final ForkJoinPool pool;

    public PrintWithPoolSize(boolean isOdd, ForkJoinPool pool) {
        this.isOdd = isOdd;
        this.pool = pool;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    System.out.println("Pool size: " + pool.getPoolSize());
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintWithPoolSize(true, pool));
    pool.invoke(new PrintWithPoolSize(false, pool));
    pool.shutdown();
}

}

3.2.9 使用 isTerminated () 方法
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class AlternatePrintTerminationCheck {
private static int count = 1;
private static final int max = 100;
private static final Object lock = new Object();

static class PrintTerminationTask extends RecursiveAction {
    private final boolean isOdd;
    private final ForkJoinPool pool;

    public PrintTerminationTask(boolean isOdd, ForkJoinPool pool) {
        this.isOdd = isOdd;
        this.pool = pool;
    }

    @Override
    protected void compute() {
        synchronized (lock) {
            while (count <= max) {
                if ((count % 2 != 0 && isOdd) || (count % 2 == 0 && !isOdd)) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                    lock.notify();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
            if (pool.isTerminated()) {
                System.out.println("Pool is terminated");
            }
        }
    }
}

public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool(2);
    pool.invoke(new PrintTerminationTask(true, pool));
    pool.invoke(new PrintTerminationTask(false, pool));
    pool.shutdown();
    while (!pool.isTerminated()) {
        // 等待池终止
    }
}

}

3.2.10 使用自定义 ForkJoinPool
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.atomic.AtomicInteger;

public class AlternatePrintCustomForkJoinPool {
private static int count = 1;
private static final int max = 100;
private static final AtomicInteger currentTurn = new AtomicInteger(0);

static class CustomForkJoinPool extends ForkJoinPool {
    public CustomForkJoinPool(int parallelism) {
        super(parallelism);
    }

    @Override
    protected ForkJoinWorkerThreadFactory getWorkerThreadFactory() {
        return new ForkJoinPool.ForkJoinWorkerThreadFactory() {
            @Override
            public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
                ForkJoinWorkerThread thread = super.getWorkerThreadFactory().newThread(pool);
                thread.setName("CustomPrintThread-" + currentTurn.getAndIncrement());
                return thread;
            }
        };
    }
}

static class PrintAction extends RecursiveAction {
    @Override
    protected void compute() {
        while (count <= max) {
            int threadId = Integer.parseInt(Thread.currentThread().getName().split("-")[1]);
            if (threadId % 2 == 0) { // 偶数线程ID打印奇数
                if (count % 2 != 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                }
            } else { // 奇数线程ID打印偶数
                if (count % 2 == 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + count++);
                }
            }
            // 模拟工作
            for (int i = 0; i < 100000; i++) {
                // 空循环
            }
        }
    }
}

public static void main(String[] args) {
    CustomForkJoinPool pool = new CustomForkJoinPool(2);
    pool.invoke(new PrintAction());
    pool.invoke(new PrintAction());
    pool.shutdown();
}

}

  1. 生产者 - 消费者模式
    4.1 基于阻塞队列的实现
    4.1.1 使用 ArrayBlockingQueue
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;

public class AlternatePrintArrayBlockingQueue {
private static final int MAX = 100;
private static final BlockingQueue queue = new ArrayBlockingQueue<>(1);

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            queue.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            queue.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.put(i);
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintArrayBlockingQueue::printOdd, "Thread-1").start();
    new Thread(AlternatePrintArrayBlockingQueue::printEven, "Thread-2").start();
}

}

4.1.2 使用 LinkedBlockingQueue
import java.util.concurrent.LinkedBlockingQueue;

public class AlternatePrintLinkedBlockingQueue {
private static final int MAX = 100;
private static final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(1);

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            queue.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            queue.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.put(i);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintLinkedBlockingQueue::printOdd, "Thread-1").start();
    new Thread(AlternatePrintLinkedBlockingQueue::printEven, "Thread-2").start();
}

}

4.1.3 使用 PriorityBlockingQueue
import java.util.concurrent.PriorityBlockingQueue;

public class AlternatePrintPriorityBlockingQueue {
private static final int MAX = 100;
private static final PriorityBlockingQueue queue = new PriorityBlockingQueue<>();

public static void print() {
    try {
        int threadId = Integer.parseInt(Thread.currentThread().getName().split("-")[1]);
        for (int i = threadId; i <= MAX; i += 2) {
            queue.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            // 等待另一个线程打印
            while (queue.size() > 1) {
                Thread.sleep(10);
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintPriorityBlockingQueue::print, "Thread-1").start();
    new Thread(AlternatePrintPriorityBlockingQueue::print, "Thread-2").start();
}

}

4.1.4 使用 SynchronousQueue
import java.util.concurrent.SynchronousQueue;

public class AlternatePrintSynchronousQueue {
private static final int MAX = 100;
private static final SynchronousQueue queue = new SynchronousQueue<>();

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            queue.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            queue.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.put(i);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintSynchronousQueue::printOdd, "Thread-1").start();
    new Thread(AlternatePrintSynchronousQueue::printEven, "Thread-2").start();
}

}

4.1.5 使用 DelayQueue
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

class DelayedElement implements Delayed {
private final int value;
private final long delayTime;

public DelayedElement(int value, long delayTime) {
    this.value = value;
    this.delayTime = delayTime;
}

@Override
public long getDelay(TimeUnit unit) {
    return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}

@Override
public int compareTo(Delayed o) {
    return Long.compare(this.delayTime, ((DelayedElement) o).delayTime);
}

public int getValue() {
    return value;
}

}

public class AlternatePrintDelayQueue {
private static final int MAX = 100;
private static final DelayQueue queue = new DelayQueue<>();

public static void print() {
    try {
        int threadId = Integer.parseInt(Thread.currentThread().getName().split("-")[1]);
        for (int i = threadId; i <= MAX; i += 2) {
            queue.put(new DelayedElement(i, System.currentTimeMillis() + 10));
            DelayedElement element = queue.take();
            System.out.println(Thread.currentThread().getName() + ": " + element.getValue());
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintDelayQueue::print, "Thread-1").start();
    new Thread(AlternatePrintDelayQueue::print, "Thread-2").start();
}

}

4.1.6 使用 LinkedTransferQueue
import java.util.concurrent.LinkedTransferQueue;

public class AlternatePrintLinkedTransferQueue {
private static final int MAX = 100;
private static final LinkedTransferQueue queue = new LinkedTransferQueue<>();

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            queue.transfer(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            queue.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.transfer(i);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintLinkedTransferQueue::printOdd, "Thread-1").start();
    new Thread(AlternatePrintLinkedTransferQueue::printEven, "Thread-2").start();
}

}

4.1.7 使用 LinkedBlockingDeque
import java.util.concurrent.LinkedBlockingDeque;

public class AlternatePrintLinkedBlockingDeque {
private static final int MAX = 100;
private static final LinkedBlockingDeque deque = new LinkedBlockingDeque<>(1);

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            deque.putFirst(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            deque.takeLast(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            deque.takeFirst(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            deque.putLast(i);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintLinkedBlockingDeque::printOdd, "Thread-1").start();
    new Thread(AlternatePrintLinkedBlockingDeque::printEven, "Thread-2").start();
}

}

4.1.8 使用 BlockingDeque 的双端操作
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

public class AlternatePrintBlockingDeque {
private static final int MAX = 100;
private static final BlockingDeque deque = new LinkedBlockingDeque<>(1);

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            deque.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            deque.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            deque.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            deque.put(i);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintBlockingDeque::printOdd, "Thread-1").start();
    new Thread(AlternatePrintBlockingDeque::printEven, "Thread-2").start();
}

}

4.1.9 使用 TransferQueue 的 tryTransfer 方法
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;

public class AlternatePrintTryTransfer {
private static final int MAX = 100;
private static final TransferQueue queue = new LinkedTransferQueue<>();

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            while (!queue.tryTransfer(i)) {
                Thread.sleep(10); // 重试
            }
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue.take(); // 等待偶数线程处理
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void printEven() {
    try {
        for (int i = 2; i <= MAX; i += 2) {
            queue.take(); // 等待奇数线程放入
            System.out.println(Thread.currentThread().getName() + ": " + i);
            while (!queue.tryTransfer(i)) {
                Thread.sleep(10); // 重试
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

public static void main(String[] args) {
    new Thread(AlternatePrintTryTransfer::printOdd, "Thread-1").start();
    new Thread(AlternatePrintTryTransfer::printEven, "Thread-2").start();
}

}

4.1.10 使用两个队列实现
import java.util.concurrent.LinkedBlockingQueue;

public class AlternatePrintTwoQueues {
private static final int MAX = 100;
private static final LinkedBlockingQueue queue1 = new LinkedBlockingQueue<>();
private static final LinkedBlockingQueue queue2 = new LinkedBlockingQueue<>();

public static void printOdd() {
    try {
        for (int i = 1; i <= MAX; i += 2) {
            queue1.put(i);
            System.out.println(Thread.currentThread().getName() + ": " + i);
            queue2.take(); // 等待偶数线程确认
        }
    } catch (InterruptedException e) {
        Thread.currentThread().
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐