线程按次序执行队列任务

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();// 激活线程序列进行处理
        }
    }
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页