java多线程JUC常用辅助类详解

1.countDownLatch

减法计数器:实现调用几次线程后,在触发另一个任务

简单代码实现:

举例说明:就像五个人在同一房间里,有一个看门的大爷,当五个人都出去后,他才能锁门,也就是说 执行5次出门这个动作的线程后,才出发了锁门的这个动作

import java.util.concurrent.CountDownLatch;
/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-24 16:55
 **/
public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        System.out.println("door is open");
        for (int i = 1; i <= 5 ; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+" is going out");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("door is closed");
    }
}

代码运行结果:

基本原理:

countDownLatch.countDown(); // 数量-1

countDownLatch.await(); // 等待计数器归零,然后再向下执行

每次有线程调用 countDown() 数量-1,假设计数器变为0,countDownLatch.await() 就会被唤醒,继续执行!

2.CyclicBarrier

这里我们简单理解为 加法计数器

简单代码实现:

举例说明:这里只要集齐7颗龙珠,就执行 打印 “7颗龙珠集齐了”的线程,这里我们先设置线程计数为8,看看会不会执行打印的线程,然后在执行计数为7的情况

1.cyclicBarrier计数为8的时候,执行线程数量为7的时候:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-24 17:31
 **/
public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(8,new myThread());
        for (int i = 1; i <= 7 ; i++) {
            int finalI = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
class myThread implements Runnable{
    @Override
    public void run() {
        System.out.println("7颗龙珠集齐啦");
    }
}

执行结果:

2.cyclicBarrier计数为1的时候,执行线程数量为7的时候:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-24 17:31
 **/
public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread());
        for (int i = 1; i <= 7 ; i++) {
            int finalI = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
class myThread implements Runnable{
    @Override
    public void run() {
        System.out.println("7颗龙珠集齐啦");
    }
}

执行结果:

可以看到

  CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread());

当执行完7个线程后,才会执行一个实现了Runnable接口的线程

3.Semaphore

简单代码实现:
举例说明:抢车位 ,6个车,最多同时只能有三个车进

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-24 18:26
 **/
public class SemaphoreTest {
    public static void main(String[] args)  {
        //线程数量 ,停车位,,6辆车在等,最多只能同时进来三个 限流
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 6 ; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();//获得
                    System.out.println(Thread.currentThread().getName()+"抢到车位了");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+"离开车位了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release(); //释放
                }
            },String.valueOf(i)).start();
        }
    }
}

运行结果:

原理说明:

semaphore.acquire() ; 获得,假设如果已经满了,等待,等待被释放为止!
semaphore.release() ; 释放,会将当前的信号量释放 + 1,然后唤醒等待的线程!

作用: 多个共享资源互斥的使用!并发限流,控制最大的线程数!

以上就是java多线程JUC常用辅助类详解的详细内容,更多关于java多线程JUC辅助类的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解JUC 常用4大并发工具类

    什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: CountDownLatch CyclicBarrier Semaphore ExChanger CountDownLatch: CountDownLatch,俗称闭锁,作用是类似加强版的Join,是让一组线程等待其他的线程完成工作以后才执行 就比如在启动框架服务的时候,我们主线程需要在环境线程初始化完成之后

  • Java并发编程之常用的辅助类详解

    1.CountDownLatch 1.2.示例:班长锁门问题 问题描述:假如有7个同学晚上上自习,钥匙在班长手上,并且要负责锁门.班长必须要等所有人都走光了,班长才能关灯锁门.这6个同学的顺序是无序的,不知道它们是何时离开.6个同学各上各的自习,中间没有交互.假如说6个学生是普通线程,班长是主线程,如何让主线程要等一堆线程运行完了,主线程才能运行完成呢. public class CountDownLatchDemo { public static void main(String[] args

  • 了解JAVA并发工具常用设计套路

    前言 在学习JAVA并发工具时,分析JUC下的源码,发现有三个利器:状态.队列.CAS. 状态 一般是state属性,如AQS源码中的状态,是整个工具的核心,一般操作的执行都要看当前状态是什么, 由于状态是多线程共享的,所以都是volatile修饰,保证线程直接内存可见. /** * AbstractQueuedSynchronizer中的状态 */ private volatile int state; /** * Status field, taking on only the values

  • java并发编程工具类JUC之ArrayBlockingQueue

    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlockingQueue中插入元素.获取元素的时候,不会导致任何并发问题(元素被插入多次.处理多次等问题). 从java BlockingQueue可以引申出一个概念:阻塞队列,是指队列本身可以阻塞线程向队列里面插入元素,或者阻塞线程从队列里面获取元素.比如:当一个线程尝试去从一个空队列里面获取元素的时候,这个线

  • java并发编程专题(十)----(JUC原子类)基本类型详解

    这一节我们先来看一下基本类型: AtomicInteger, AtomicLong, AtomicBoolean.AtomicInteger和AtomicLong的使用方法差不多,AtomicBoolean因为比较简单所以方法比前两个都少,那我们这节主要挑AtomicLong来说,会使用一个,其余的大同小异. 1.原子操作与一般操作异同 我们在说原子操作之前为了有个对比为什么需要这些原子类而不是普通的基本数据类型就能满足我们的使用要求,那就不得不提原子操作不同的地方. 当你在操作一个普通变量时,

  • java多线程JUC常用辅助类详解

    1.countDownLatch 减法计数器:实现调用几次线程后,在触发另一个任务 简单代码实现: 举例说明:就像五个人在同一房间里,有一个看门的大爷,当五个人都出去后,他才能锁门,也就是说 执行5次出门这个动作的线程后,才出发了锁门的这个动作 import java.util.concurrent.CountDownLatch; /** * @program: juc * @description * @author: 不会编程的派大星 * @create: 2021-04-24 16:55

  • Java多线程案例之定时器详解

    目录 一.什么是定时器 二.标准库中的定时器(timer) 2.1什么是定时器 2.2定时器的使用 三.实现定时器 3.1什么是定时器 3.2最终实现代码 一.什么是定时器 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码 定时器是一种实际开发中非常常用的组件,我们举几个例子: 1.比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连 2.比如一个 Map, 希望里面的某个 key 在 3s 之后过期(自动删除

  • Java多线程用法的实例详解

    Java多线程用法的实例详解 前言: 最全面的java多线程用法解析,如果你对Java的多线程机制并没有深入的研究,那么本文可以帮助你更透彻地理解Java多线程的原理以及使用方法. 1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例.Thread构造函数: public Thread( ); p

  • Java多线程通信实现方式详解

    这篇文章主要介绍了Java多线程通信实现方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 线程通信的方式: 1.共享变量 线程间通信可以通过发送信号,发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步代码块里读取hasDataToProcess这个成员变量.这个简单的例子使用了一个持有信号的对象,并提供了set和get方法. pu

  • Java多线程 线程状态原理详解

    这篇文章主要介绍了Java多线程 线程状态原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java.lang.Thread.State枚举定义了6种线程状态. NEW: 尚未启动(start)的线程的线程状态 RUNNABLE: 运行状态,但线程可能正在JVM中执行,也可能在等待CPU调度 BLOCKED: 线程阻塞,等待监视器锁以进入同步代码块/方法 WAITING: 等待状态.使用以下不带超时的方式时会进入:Object.wait.

  • Java多线程编程综合案例详解

    目录 Java多线程综合案例 数字加减 生产电脑 竞争抢答 Java多线程综合案例 数字加减 设计4个线程对象,两个线程执行减操作,两个线程执行加操作 public class ThreadDemo{ public static void main(String[] args) throws Exception { Resource res=new Resource(); AddThread at=new AddThread(res); SubThread st=new SubThread(re

  • Java多线程解决龟兔赛跑问题详解

    目录 多线程4(龟兔赛跑-休眠线程) 1.题目 2.解题思路 3.代码详解 多线程4(龟兔赛跑-休眠线程) 1.题目 在龟兔赛跑中,领先的兔子因为通宵写博客,中途太累睡着了,跑输了乌龟.这个故事说明了兔子是爱学习的同学.咳咳,通宵是不可取的,大家别学. 实现:使用线程休眠模拟龟兔赛跑比赛 2.解题思路 创建一个类:RaceFrame,继承了JFrame.用来界面显示两个文本区域,用来输出乌龟和兔子的比赛记录,比赛开始按钮用来开始比赛. 编写内部类:Rabbit,该类实现了Runnable接口,在

  • java多线程中线程封闭详解

    线程封闭的概念 访问共享变量时,通常要使用同步,所以避免使用同步的方法就是减少共享数据的使用,这种技术就是线程封闭. 实现线程封闭的方法 1:ad-hoc线程封闭 这是完全靠实现者控制的线程封闭,他的线程封闭完全靠实现者实现.也是最糟糕的一种线程封闭.所以我们直接把他忽略掉吧. 2:栈封闭 栈封闭是我们编程当中遇到的最多的线程封闭.什么是栈封闭呢?简单的说就是局部变量.多个线程访问一个方法,此方法中的局部变量都会被拷贝一分儿到线程栈中.所以局部变量是不被多个线程所共享的,也就不会出现并发问题.所

  • JAVA多线程之方法 JOIN详解及实例代码

    JAVA多线程 JOIN 对于Java开发人员,多线程应该是必须熟练应用的知识点,特别是开发基于Java语言的产品.本文将深入浅出的表述Java多线程的知识点,在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用. 如何才能深入浅出呢,我的理解是带着问题,而不是泛泛的看.所以该系列基本以解决问题为主,当然我也非常希望读者能够提出更好的解决问题的方案以及提出更多的问题.由于水平有限,如果有什么错误之处,请大家提出,共同讨论,总之,我希望

  • Java多线程并发FutureTask使用详解

    目录 基本使用 代码分析 继承关系 Future RunnableFuture FutureTask 状态 属性 内部类 构造方法 检索 FutureTask 状态 取消操作 计算结果 立刻获取结果或异常 run 方法组 本文基于最新的 OpenJDK 代码,预计发行版本为 19 . Java 的多线程机制本质上能够完成两件事情,异步计算和并发.并发问题通过解决线程安全的一系列 API 来解决:而异步计算,常见的使用是 Runnable 和 Callable 配合线程使用. FutureTask

随机推荐