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

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

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

多线程轮询执行问题解决方案: 比如有三个线程 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;
        }
    }
}

相关文章

Head First 设计模式总结

Head First 设计模式总结

设计模式读书总结链接: https://pan.baidu.com/s/1fjM5mhJH67wN73sUhOiZTA 密码: od09...

leetcode - 2两数相加

leetcode - 2两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和...

leetcode - 1.两数之和

leetcode - 1.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。示...

发表评论

访客

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