Java 多线程打印的19种实现方法
下面我将为你详细介绍19种不同的Java多线程打印实现方法:
- synchronized + wait/notify 基础版
java
public class Method1_BasicSynchronized {
private static final Object lock = new Object();
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock) {
while (number <= MAX) {
if (number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
lock.notify();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
lock.notify();
}
}, "Odd-Thread").start();
new Thread(() -> {
synchronized (lock) {
while (number <= MAX) {
if (number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
lock.notify();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}, "Even-Thread").start();
}
}
- ReentrantLock + Condition 精确控制
java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Method2_ReentrantLock {
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition oddCondition = lock.newCondition();
private static final Condition evenCondition = lock.newCondition();
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
lock.lock();
try {
while (number % 2 == 0) {
oddCondition.await();
}
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
evenCondition.signal();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
lock.lock();
try {
while (number % 2 == 1) {
evenCondition.await();
}
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
oddCondition.signal();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}, "Even-Thread").start();
}
}
- Semaphore 双信号量
java
import java.util.concurrent.Semaphore;
public class Method3_Semaphore {
private static final Semaphore oddSemaphore = new Semaphore(1);
private static final Semaphore evenSemaphore = new Semaphore(0);
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
try {
oddSemaphore.acquire();
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
evenSemaphore.release();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
try {
evenSemaphore.acquire();
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
oddSemaphore.release();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Even-Thread").start();
}
}
- LockSupport 无锁同步
java
import java.util.concurrent.locks.LockSupport;
public class Method4_LockSupport {
private static int number = 1;
private static final int MAX = 10;
private static Thread oddThread, evenThread;
public static void main(String[] args) {
oddThread = new Thread(() -> {
while (number <= MAX) {
if (number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
LockSupport.unpark(evenThread);
} else {
LockSupport.park();
}
}
}, "Odd-Thread");
evenThread = new Thread(() -> {
while (number <= MAX) {
if (number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
LockSupport.unpark(oddThread);
} else {
LockSupport.park();
}
}
}, "Even-Thread");
oddThread.start();
evenThread.start();
}
}
- CyclicBarrier 循环屏障
java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Method5_CyclicBarrier {
private static final CyclicBarrier barrier = new CyclicBarrier(2);
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
try {
if (number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
Thread.currentThread().interrupt();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
try {
if (number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
Thread.currentThread().interrupt();
}
}
}, "Even-Thread").start();
}
}
- CountDownLatch 倒计时门闩
java
import java.util.concurrent.CountDownLatch;
public class Method6_CountDownLatch {
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MAX; i++) {
CountDownLatch currentLatch = new CountDownLatch(1);
CountDownLatch nextLatch = new CountDownLatch(1);
final int currentNumber = number;
new Thread(() -> {
try {
currentLatch.await();
System.out.println(Thread.currentThread().getName() + ": " + currentNumber);
nextLatch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Thread-" + currentNumber).start();
currentLatch.countDown();
nextLatch.await();
number++;
}
}
}
- BlockingQueue 阻塞队列
java
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Method7_BlockingQueue {
private static final BlockingQueue<Integer> oddQueue = new ArrayBlockingQueue<>(1);
private static final BlockingQueue<Integer> evenQueue = new ArrayBlockingQueue<>(1);
private static int number = 1;
private static final int MAX = 10;
static {
try {
oddQueue.put(0);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
try {
oddQueue.take();
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
evenQueue.put(0);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
try {
evenQueue.take();
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
oddQueue.put(0);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Even-Thread").start();
}
}
- Phaser 相位器
java
import java.util.concurrent.Phaser;
public class Method8_Phaser {
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
Phaser phaser = new Phaser(2);
new Thread(() -> {
while (number <= MAX) {
if (number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
phaser.arriveAndAwaitAdvance();
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
if (number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
phaser.arriveAndAwaitAdvance();
}
}, "Even-Thread").start();
}
}
- Exchanger 交换器
java
import java.util.concurrent.Exchanger;
public class Method9_Exchanger {
private static int number = 1;
private static final int MAX = 10;
public static void main(String[] args) {
Exchanger<Boolean> exchanger = new Exchanger<>();
new Thread(() -> {
boolean canPrint = true;
while (number <= MAX) {
try {
if (canPrint && number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
canPrint = exchanger.exchange(!canPrint);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
boolean canPrint = false;
while (number <= MAX) {
try {
if (canPrint && number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
canPrint = exchanger.exchange(!canPrint);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Even-Thread").start();
}
}
- CompletableFuture 链式调用
java
import java.util.concurrent.CompletableFuture;
public class Method10_CompletableFuture {
private static final int MAX = 10;
public static void main(String[] args) {
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
for (int i = 1; i <= MAX; i++) {
final int current = i;
future = future.thenRunAsync(() ->
System.out.println(Thread.currentThread().getName() + ": " + current)
);
}
future.join();
}
}
- 线程池 + Future 任务管理
java
import java.util.concurrent.*;
public class Method11_ThreadPoolFuture {
private static final int MAX = 10;
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<?> oddFuture = executor.submit(() -> {
for (int i = 1; i <= MAX; i += 2) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
});
Future<?> evenFuture = executor.submit(() -> {
for (int i = 2; i <= MAX; i += 2) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
});
oddFuture.get();
evenFuture.get();
executor.shutdown();
}
}
- AtomicInteger + 自旋锁
java
import java.util.concurrent.atomic.AtomicInteger;
public class Method12_AtomicSpin {
private static final AtomicInteger number = new AtomicInteger(1);
private static final int MAX = 10;
private static volatile int turn = 1;
public static void main(String[] args) {
new Thread(() -> {
while (number.get() <= MAX) {
if (turn == 1 && number.get() <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number.getAndIncrement());
turn = 2;
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number.get() <= MAX) {
if (turn == 2 && number.get() <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number.getAndIncrement());
turn = 1;
}
}
}, "Even-Thread").start();
}
}
- ReadWriteLock 读写锁
java
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Method13_ReadWriteLock {
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
private static int number = 1;
private static final int MAX = 10;
private static volatile boolean oddTurn = true;
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
lock.writeLock().lock();
try {
if (oddTurn && number <= MAX && number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
oddTurn = false;
}
} finally {
lock.writeLock().unlock();
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
lock.writeLock().lock();
try {
if (!oddTurn && number <= MAX && number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
oddTurn = true;
}
} finally {
lock.writeLock().unlock();
}
}
}, "Even-Thread").start();
}
}
- StampedLock 邮戳锁
java
import java.util.concurrent.locks.StampedLock;
public class Method14_StampedLock {
private static final StampedLock lock = new StampedLock();
private static int number = 1;
private static final int MAX = 10;
private static volatile boolean oddTurn = true;
public static void main(String[] args) {
new Thread(() -> {
while (number <= MAX) {
long stamp = lock.writeLock();
try {
if (oddTurn && number <= MAX && number % 2 == 1) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
oddTurn = false;
}
} finally {
lock.unlockWrite(stamp);
}
}
}, "Odd-Thread").start();
new Thread(() -> {
while (number <= MAX) {
long stamp = lock.writeLock();
try {
if (!oddTurn && number <= MAX && number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
oddTurn = true;
}
} finally {
lock.unlockWrite(stamp);
}
}
}, "Even-Thread").start();
}
}
- ThreadLocal 线程局部变量
java
public class Method15_ThreadLocal {
private static final ThreadLocal<Integer> threadNumber = new ThreadLocal<>();
private static volatile int current = 1;
private static final int MAX = 10;
public static void main(String[] args) {
threadNumber.set(1);
Thread oddThread = new Thread(() -> {
threadNumber.set(1);
while (current <= MAX) {
if (current % 2 == 1 && threadNumber.get() == current) {
System.out.println(Thread.currentThread().getName() + ": " + current++);
threadNumber.set(threadNumber.get() + 2);
}
}
}, "Odd-Thread");
Thread evenThread = new Thread(() -> {
threadNumber.set(2);
while (current <= MAX) {
if (current % 2 == 0 && threadNumber.get() == current) {
System.out.println(Thread.currentThread().getName() + ": " + current++);
threadNumber.set(threadNumber.get() + 2);
}
}
}, "Even-Thread");
oddThread.start();
evenThread.start();
}
}
- ForkJoinPool 分而治之
java
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class Method16_ForkJoin {
private static final int MAX = 10;
static class PrintTask extends RecursiveAction {
private final int start;
private final int end;
PrintTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if (end - start <= 1) {
System.out.println(Thread.currentThread().getName() + ": " + start);
} else {
int mid = (start + end) / 2;
PrintTask left = new PrintTask(start, mid);
PrintTask right = new PrintTask(mid, end);
invokeAll(left, right);
}
}
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(new PrintTask(1, MAX + 1));
pool.shutdown();
}
}
- 信号量数组(多线程扩展)
java
import java.util.concurrent.Semaphore;
public class Method17_SemaphoreArray {
private static final int THREAD_COUNT = 3;
private static final int MAX = 12;
private static int number = 1;
private static final Semaphore[] semaphores = new Semaphore[THREAD_COUNT];
static {
for (int i = 0; i < THREAD_COUNT; i++) {
semaphores[i] = new Semaphore(i == 0 ? 1 : 0);
}
}
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
final int threadIndex = i;
new Thread(() -> {
while (number <= MAX) {
try {
semaphores[threadIndex].acquire();
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
}
semaphores[(threadIndex + 1) % THREAD_COUNT].release();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Thread-" + (threadIndex + 1)).start();
}
}
}
- 条件队列 + 状态模式
java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Method18_StatePattern {
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition[] conditions = new Condition[3];
private static int number = 1;
private static final int MAX = 12;
private static int state = 0;
static {
for (int i = 0; i < conditions.length; i++) {
conditions[i] = lock.newCondition();
}
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
final int threadState = i;
new Thread(() -> {
while (number <= MAX) {
lock.lock();
try {
while (state != threadState && number <= MAX) {
conditions[threadState].await();
}
if (number <= MAX) {
System.out.println(Thread.currentThread().getName() + ": " + number++);
state = (state + 1) % 3;
conditions[state].signal();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}, "Thread-" + (threadState + 1)).start();
}
}
}
- 反应式编程(Reactive Streams)
java
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
import java.util.concurrent.atomic.AtomicInteger;
public class Method19_ReactiveStreams {
private static final int MAX = 10;
static class NumberSubscriber implements Flow.Subscriber<Integer> {
private Flow.Subscription subscription;
private final String name;
NumberSubscriber(String name) {
this.name = name;
}
@Override
public void onSubscribe(Flow.Subscription subscription) {
this.subscription = subscription;
subscription.request(1);
}
@Override
public void onNext(Integer item) {
System.out.println(name + ": " + item);
subscription.request(1);
}
@Override
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
@Override
public void onComplete() {
System.out.println(name + ": Completed");
}
}
public static void main(String[] args) throws InterruptedException {
SubmissionPublisher<Integer> publisher = new SubmissionPublisher<>();
publisher.subscribe(new NumberSubscriber("Subscriber-1"));
publisher.subscribe(new NumberSubscriber("Subscriber-2"));
AtomicInteger counter = new AtomicInteger(1);
while (counter.get() <= MAX) {
publisher.submit(counter.getAndIncrement());
Thread.sleep(100);
}
publisher.close();
Thread.sleep(1000);
}
}
方法总结对比
方法 类型 性能 复杂度 适用场景
synchronized 内置锁 中等 简单 基础同步需求
ReentrantLock 显式锁 高 中等 复杂同步控制
Semaphore 信号量 高 中等 资源访问控制
LockSupport 底层控制 很高 中等 精细线程控制
CyclicBarrier 屏障 中等 中等 多阶段任务
CountDownLatch 门闩 中等 简单 一次性同步
BlockingQueue 队列 高 中等 生产者消费者
Phaser 相位器 高 复杂 复杂阶段任务
Exchanger 交换器 中等 中等 线程间数据交换
CompletableFuture 异步 高 复杂 异步编程
线程池+Future 任务管理 高 中等 任务执行管理
Atomic+自旋 无锁 很高 简单 简单原子操作
ReadWriteLock 读写锁 高 中等 读写分离场景
StampedLock 乐观锁 很高 复杂 读多写少场景
ThreadLocal 线程局部 高 简单 线程隔离数据
ForkJoinPool 分治 很高 复杂 计算密集型任务
信号量数组 扩展控制 高 中等 多线程顺序控制
状态模式 设计模式 中等 复杂 复杂状态管理
Reactive Streams 反应式 高 复杂 异步流处理
这些方法涵盖了Java并发编程的各个方面,从基础的同步机制到高级的并发框架,你可以根据具体的性能需求、复杂度要求和业务场景选择合适的方法。