豆包 Java 多线程交替打印 50 种实现方法
3.1.6 使用 ScheduledExecutorService 的 schedule 方法。2.3.8 使用 getNumberWaiting () 方法。
Java 多线程交替打印 50 种实现方法
-
基础同步机制实现
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();
}
}
- 高级并发工具实现
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();
}
}
- 线程池与框架实现
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();
}
}
- 生产者 - 消费者模式
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().
更多推荐




所有评论(0)