第79题JAVA高级技术-多线程13(线程按序交替执行)

Posted 小虚竹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第79题JAVA高级技术-多线程13(线程按序交替执行)相关的知识,希望对你有一定的参考价值。

回城传送–》《JAVA筑基100例》

文章目录

零、前言

​ 今天是学习 JAVA语言 打卡的第79天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 ),读完文章之后,按解题思路,自己再实现一遍。在小虚竹JAVA社区 中对应的 【打卡贴】打卡,今天的任务就算完成了。

​ 因为大家都在一起学习同一篇文章,所以有什么问题都可以在群里问,群里的小伙伴可以迅速地帮到你,一个人可以走得很快,一群人可以走得很远,有一起学习交流的战友,是多么幸运的事情。

​ 学完后,自己写篇学习报告的博客,可以发布到小虚竹JAVA社区 ,供学弟学妹们参考。

​ 我的学习策略很简单,题海策略+ 费曼学习法。如果能把这100题都认认真真自己实现一遍,那意味着 JAVA语言 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。

一、题目描述

题目:有a、b、c三个线程,使得它们按照abc依次执行10次。

二、解题思路

控制执行线程变量flag,利用lock锁来保证线程安全,使用comdition来堵塞线程和通信。

Condition:

  • condition接口描述了可能会与锁有关的条件变量。这些用法上与使用object.wait访问隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个lock可能与多个Condition对象关联。为了避免兼容性问题,Condition方法的名称与对应的objec版本中的不同。
  • 在condition对象中:
    • await方法//是等待;这时锁会释放
    • signalAll方法//通知,线程等待结束,往下执行
  • Condition实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,请使用其newCondition()方法。

创建一个类:AbcAlternateDemo1

创建一个内部类:Alternate

内部类定义一个属性:线程启动的顺序标识flag

写三个方法:

  • loopA():先上锁,判断flag是不是1,不是则等待conditionA.await(); 如果是则输出,flag是2,通知线程往下执行conditionA.signalAll()。
  • loopB():先上锁,判断flag是不是2,不是则等待conditionA.await(); 如果是则输出,flag是3,通知线程往下执行conditionA.signalAll()。
  • loopC():先上锁,判断flag是不是3,不是则等待conditionA.await(); 如果是则输出,flag是1,通知线程往下执行conditionA.signalAll()。

三、代码详解

AbcAlternateDemo1

package com.xiaoxuzhu;

/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改记录:
 * 修改后版本	        修改人		修改日期			修改内容
 * 2022/5/15.1	    xiaoxuzhu		2022/5/15		    Create
 * </pre>
 * @date 2022/5/15
 */
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改记录:
 * 修改后版本	        修改人		修改日期			修改内容
 * 2022/5/15.1	    xiaoxuzhu		2022/5/15		    Create
 * </pre>
 * @date 2022/5/15
 */
public class AbcAlternateDemo1 

    public static void main(String[] args) 
        Alternate alternate = new Alternate();
        new Thread(new Runnable() 
            @Override
            public void run() 
                for (int i = 0; i < 10; i++) 
                    alternate.loopA(i);
                
            
        ,"A").start();

        new Thread(new Runnable() 
            @Override
            public void run() 
                for (int i = 0; i < 10; i++) 
                    alternate.loopB(i);
                
            
        ,"B").start();

        new Thread(new Runnable() 
            @Override
            public void run() 
                for (int i = 0; i < 10; i++) 
                    alternate.loopC(i);
                
            
        ,"C").start();
    

    static class Alternate

        /**
         * //线程启动的顺序标识
         **/
        private int flag = 1;

        private Lock lock = new ReentrantLock();

        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();

        public void loopA(int loopNum)
            lock.lock();
            try 
                if(flag !=1)
                    conditionA.await();
                
                for (int i = 1; i <= 1; i++) 
                    System.out.println(Thread.currentThread().getName()+":"+"--"+loopNum+"--"+ i);
                
                flag =2;
                conditionB.signalAll();
            catch (Exception e)
                e.printStackTrace();
            finally 
                lock.unlock();
            
        

        public void loopB(int loopNum)
            lock.lock();
            try 
                if(flag !=2)
                    conditionB.await();
                
                for (int i = 1; i <= 1; i++) 
                    System.out.println(Thread.currentThread().getName()+":"+"--"+loopNum+"--"+ i);
                
                flag =3;
                conditionC.signalAll();
            catch (Exception e)
                e.printStackTrace();
            finally 
                lock.unlock();
            
        

        public void loopC(int loopNum)
            lock.lock();
            try 
                if(flag !=3)
                    conditionC.await();
                
                for (int i = 1; i <= 1; i++) 
                    System.out.println(Thread.currentThread().getName()+":"+"--"+loopNum+"--"+ i);
                
                flag =1;
                System.out.println("----------------------");
                conditionA.signalAll();
            catch (Exception e)
                e.printStackTrace();
            finally 
                lock.unlock();
            
        

    


四、推荐专栏

《JAVA从零到壹》

《JAVA筑基100例》

五、示例源码下载

关注下面的公众号,回复筑基+题目号

筑基79

以上是关于第79题JAVA高级技术-多线程13(线程按序交替执行)的主要内容,如果未能解决你的问题,请参考以下文章

java 面试题 -- 线程 按序 交替

多线程按序交替打印

LeetCode 多线程练习1(1114. 按序打印 / 1115. 交替打印FooBar)

面试题:用程序实现两个线程交替打印 0~100 的奇偶数

juc高级特性——虚假唤醒 / Condition / 按序交替 / ReadWriteLock / 线程八锁

JUC-Condition和Lock实践-线程按序交替执行