美文网首页
线程顺序执行T1->T2->T3->T3->T2->T1->T1

线程顺序执行T1->T2->T3->T3->T2->T1->T1

作者: wyn_做自己 | 来源:发表于2021-05-28 12:24 被阅读0次

    今日份鸡汤:这个世界从不缺少看笑话的人,做不到雪中送炭,也请不要雪上加霜,请保持住那最后一点的善良。

    思路:控制线程精确的执行(阻塞或者唤醒),想到的是lock提供的condition,利用await()方法和signal()来实现精准的顺序执行,但是考虑到不是一直顺序循环执行,查看一下规律,然后进行分组:T1->T2->T3(第一组,index=1), T3->T2->T1(第二组,index=2),T1->T2->T3(第三组,index=3),T3->T2->T1(第四组,index=4),这样就知道了index为奇数时:T1执行完唤醒T2,T2执行完唤醒T3,T3执行完唤醒T3;index为偶数时:T1执行完唤醒T1,T2执行完唤醒T1,T3执行完唤醒T2。上代码:

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 线程顺序执行:线程1 -》 线程2 -》线程3 -》线程3 -》线程2 -》线程1
     */
    public class SignalTest {
    
        private int num = 1;
        private Lock lock = new ReentrantLock();
        private Condition condition1 = lock.newCondition();
        private Condition condition2 = lock.newCondition();
        private Condition condition3 = lock.newCondition();
    
        public void executeTh1(int index) {
            try {
                lock.lock();
                while (num != 1) {
                    condition1.await();
                }
                System.out.println(Thread.currentThread().getName() + " 开始执行啦,当前index=" + index);
                if (index % 2 == 1) {
                    num = 2;
                    condition2.signal();
                } else {
                    num = 1;
                    condition1.signal();
                }
    
            } catch (Exception e){
    
            } finally {
                lock.unlock();
            }
        }
    
        public void executeTh2(int index) {
            try {
                lock.lock();
                while (num != 2) {
                    condition2.await();
                }
                System.out.println(Thread.currentThread().getName() + " 开始执行啦,当前index=" + index);
                if (index % 2 == 1) {
    
                    num = 3;
                    condition3.signal();
                } else {
                    num = 1;
                    condition1.signal();
                }
    
            } catch (Exception e) {
    
            } finally {
                lock.unlock();
            }
        }
    
        public void executeTh3(int index) {
            try {
                lock.lock();
                while (num != 3) {
                    condition3.await();
                }
                System.out.println(Thread.currentThread().getName() + " 开始执行啦,当前index=" + index);
                if (index % 2 == 1) {
                    num = 3;
                    condition3.signal();
                } else {
                    num = 2;
                    condition2.signal();
                }
            } catch (Exception e) {
    
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            SignalTest signalTest = new SignalTest();
            new Thread(() -> {
                for(int i = 1 ; i <= 5 ; i++){
                    signalTest.executeTh1(i);
                }
            }, "线程1").start();
            new Thread(() -> {
                for(int i = 1 ; i <= 5 ; i++){
                    signalTest.executeTh2(i);
                }
            }, "线程2").start();
            new Thread(() -> {
                for(int i = 1 ; i <= 5 ; i++){
                    signalTest.executeTh3(i);
                }
            }, "线程3").start();
        }
    }
    

    执行结果打印:


    image.png

    还有一种相对简单的,顺序循环执行线程:T1->T2->T3->T1->T2->T3
    懂了上面的案例,想必这种情况就更简单了,去掉index的判断逻辑,然后顺序唤醒就可以啦~

    相关文章

      网友评论

          本文标题:线程顺序执行T1->T2->T3->T3->T2->T1->T1

          本文链接:https://www.haomeiwen.com/subject/jvkssltx.html