当前位置:首页 > 算法 > 正文内容

多线程依次顺序轮询执行方案

淙嶙7年前 (2018-10-18)算法1027

多线程轮询执行问题解决方案: 比如有三个线程 thread1 ,thread2, thread3。 规则:thread1运行 -> thread2运行 -> thread3 -> thread1 -> thread2 … 循环依次顺序执行。 例如:输出数字任务,thread1 打印 1, thread2 打印 2,thread3 打印 3, thread1 打印 4, thread2 打印 5, thread3 打印 6 …

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class TestThread {
    /**
     * 多线程轮询执行问题解决方案。
     *  比如有三个线程 thread1 ,thread2, thread3。
     *  规则:thread1 先执行任务,thread2其次 ,thread3最后执行。把这个作为一个循环依次顺序执行。
     *  例如:输出数字任务,thread1 打印 1, thread2 打印 2,thread3 打印 3,  thread1 打印 4, thread2 打印 5, thread3 打印 6 ...
     */
    private int startValue = 1;
    private List<ThreadDemo> threadList = new ArrayList<>();
    private ReentrantLock lock = new ReentrantLock();
    private volatile boolean stop = false;
    private static int limitValue = 0;
    public static void main(String[] args) {
        new TestThread().execute(3,1,100);
    }

    public void execute(int threadNum,int start,int maxValue){
        limitValue = maxValue;
        generateThreadQuene(threadNum);
        setThreadExecuteOrder(threadList);
        executePrint(start);
    }

    private void executePrint(int start){
        startValue = start;
        for ( int i =0;i<threadList.size();i++){
            ThreadDemo thread = threadList.get(i);
            if (i ==0){
                thread.setFirstStart(true);
            }
            thread.start();
        }
    }
    private void generateThreadQuene(int threadNum){
        ThreadDemo thread;
        for (int i = 0 ;i < threadNum; i++){
            thread = new ThreadDemo();
            thread.setName("thread "+i);
            threadList.add(thread);
        }
    }
    private void setThreadExecuteOrder(List<ThreadDemo> threadList){
        Condition currentCondition = lock.newCondition();
        Condition firsetCondition = currentCondition;
        Condition nextCondition;
        for (ThreadDemo thread : threadList) {
            nextCondition = lock.newCondition();
            thread.setCondition(currentCondition);
            thread.setNextCondition(nextCondition);
            currentCondition = nextCondition;
        }
        threadList.get(threadList.size()-1).setNextCondition(firsetCondition);//设置执行首尾相连
    }
    private synchronized void print(){
        System.out.println(Thread.currentThread().getName()+" print : "+ (startValue++));
        if (startValue > limitValue){
            stop = true;
        }
    }
    class ThreadDemo extends Thread{
        Condition condition;
        boolean isFirstStart;
        Condition nextCondition;
        @Override
        public void run(){
            try {
                System.out.println("thread name is "+ this.getName() +" start ...");
                lock.lock();
                if (!isFirstStart){
                    condition.await();
                }
                condition.awaitNanos(500);//保证其他线程都处于运行态,避免条件唤醒失败
                while (!stop){
                    print();//打印
                    nextCondition.signal();
                    condition.await();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                nextCondition.signal();//最后唤醒所有以免运行到最后有线程一直处于等待,没有关闭。
                lock.unlock();
            }
        }

        public void setFirstStart(boolean firstStart) {
            isFirstStart = firstStart;
        }

        public void setCondition(Condition condition) {
            this.condition = condition;
        }

        public void setNextCondition(Condition nextCondition) {
            this.nextCondition = nextCondition;
        }
    }
}

相关文章

红黑树

红黑树

红黑树是一种自平衡的二叉查找树。除了符合二叉查找树的基本特征外,还具有如下特征: 1.每个节点是红色或黑色。 2.根节点是黑色。 3.每个叶子节点都是黑色的空节点(NIL节点)。[注意:这里...

Java transient关键字使用小记

Java transient关键字使用小记

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。 2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被tran...

leetcode - 3无重复字符的最长子串

leetcode - 3无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例1: 输入: “abcabcbb”输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。示例 2:输入:...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。