package demo;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
public class ThreadOrder {
static class TaskProcess implements Runnable {
private Queue<Runnable> tasks;//获取任务的队列
private Object myLock;//本线程等待的锁
private Object nextLock;//通知下个线程的锁
private CountDownLatch latch;//通知主线程:本线程已经就绪
public TaskProcess(Queue<Runnable> tasks, Object myLock, Object nextLock, CountDownLatch latch) {
this.tasks = tasks;
this.myLock = myLock;
this.nextLock = nextLock;
this.latch = latch;
}
public void run() {
String name = Thread.currentThread().getName();//当前线程的名字
synchronized (myLock) { //拿到自己的锁后
latch.countDown();//拿到自己的锁后,通知主线程:本线程已经就绪
Runnable task;//要执行的任务
while (true) {
// 1.等待被通知执行
try {
myLock.wait();
} catch (InterruptedException e) {
System.out.println("运行异常:" + name);
notifyNextThread();//必需 通知下个线程,以防止下一个线程永久等待
return;
}
// 2.被通知后,开始获取任务并执行
task = tasks.poll();
if (task == null) {//没有任务
System.out.println("没有任务,线程退出:" + name);
notifyNextThread();//必需 通知下个线程,以防止下一个线程永久等待
return;
}
// 3.执行任务过程
task.run();
// 4.通知下一个线程执行任务
notifyNextThread();
}
}
}
private void notifyNextThread() {
synchronized (nextLock) {
nextLock.notify();
}
}
}
public static void main(String[] args) throws InterruptedException {
// 1. 定义任务队列
final Queue<Runnable> tasks = new LinkedList<Runnable>();
for (int i = 0; i < 100; i++) {
final int finalI = i;
tasks.offer(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " 执行任务:" + finalI);
}
});
}
// 2.定义执行任务的线程数(按次序执行)
// int number = 2;//TODO 修改这里可以 改变 执行任务的线程序列个数
int number = 10;//TODO 修改这里可以 改变 执行任务的线程序列个数
// 定义所有线程就绪通知机制
CountDownLatch latch = new CountDownLatch(number);
// 定义线程顺序执行用以交互的锁
Object[] locks = new Object[number];
for (int i = 0; i < number; i++) {
locks[i] = new Object();
}
for (int i = 0; i < number; i++) {
Object myLock = locks[i];
Object nextLock = locks[i < number - 1 ? i + 1 : 0];
Thread t = new Thread(new TaskProcess(tasks, myLock, nextLock, latch) {
}, "Thread-" + i);
t.start();
}
//等待所有线程就绪
latch.await();
//获取到第一个要执行的线程的锁,予以激活
Object firstLock = locks[0];
// 激活线程序列进行处理
synchronized (firstLock) {
firstLock.notify();// 激活线程序列进行处理
}
}
}
线程按次序执行队列任务
最新推荐文章于 2025-02-26 21:00:51 发布