package com.study.springCloudAlibaba;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 本类用于演示使用Semaphore和CompletableFuture来控制多线程的执行顺序
*/
public class Test2 {
public static void main(String[] args) {
// 共享计数器,用于跟踪已执行的任务数量
AtomicInteger counter = new AtomicInteger(0);
// 设置每个线程池需要执行的总循环次数
int totalIterations = 10;
// 创建一个固定大小的线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0L, java.util.concurrent.TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));
// 使用Semaphore来控制任务的顺序执行
Semaphore semaphore1 = new Semaphore(1);
Semaphore semaphore2 = new Semaphore(0);
Semaphore semaphore3 = new Semaphore(0);
// 循环直到所有线程完成预定次数的任务
while (counter.get() < totalIterations * 3) {
// 第一个线程的任务
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
try {
// 获取许可,确保按顺序执行
semaphore1.acquire();
// 增加计数器并检查是否达到总次数
if (counter.getAndIncrement() < totalIterations * 3) {
// 执行线程1的任务
System.out.println("线程1: " + Thread.currentThread().getId());
// 释放许可给下一个线程
semaphore2.release();
}
} catch (InterruptedException e) {
// 重新设置中断状态
Thread.currentThread().interrupt();
}
}, executor);
// 第二个线程的任务,依赖于第一个任务的完成
CompletableFuture<Void> future2 = future1.thenRunAsync(() -> {
try {
// 获取许可,确保按顺序执行
semaphore2.acquire();
// 增加计数器并检查是否达到总次数
if (counter.getAndIncrement() < totalIterations * 3) {
// 执行线程2的任务
System.out.println("线程2: " + Thread.currentThread().getId());
// 释放许可给下一个线程
semaphore3.release();
}
} catch (InterruptedException e) {
// 重新设置中断状态
Thread.currentThread().interrupt();
}
}, executor);
// 第三个线程的任务,依赖于第二个任务的完成
CompletableFuture<Void> future3 = future2.thenRunAsync(() -> {
try {
// 获取许可,确保按顺序执行
semaphore3.acquire();
// 增加计数器并检查是否达到总次数
if (counter.getAndIncrement() < totalIterations * 3) {
// 执行线程3的任务
System.out.println("线程3: " + Thread.currentThread().getId());
// 释放许可给第一个线程,开始下一轮循环
semaphore1.release();
}
} catch (InterruptedException e) {
// 重新设置中断状态
Thread.currentThread().interrupt();
}
}, executor);
try {
// 等待第三个线程的任务完成
future3.get();
} catch (Exception e) {
// 处理异常
e.printStackTrace();
}
}
// 关闭线程池
executor.shutdown();
}
}
三个线程交替打印线程ID
最新推荐文章于 2024-10-16 10:13:45 发布