【JUC的四大同步辅助类】

news2024/9/25 11:13:50

文章目录

  • 一、CountDownLatch
  • 二、CyclicBarrier
  • 三、Semaphore
  • 四、Phaser


提示:以下是本篇文章正文内容,下面案例可供参考

一、CountDownLatch

CountDownLatch如同火箭发射,计数只能不断减减,当到达0时即发射
场景示例:考场中有多个同学考试,每个同学写完试卷后,将试卷交给老师即可离开,老师需要收齐所有人的试卷后才能离开。

代码如下(示例)

public class Test {
    public static void main(String[] args) throws InterruptedException {
        // CountDownLatch 倒计时到0,发射(减法)

        // 考场学生人数为 6(一旦定下就不能在增加)
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    // 模拟每个学生完成试卷的时间不同(线程休眠随机时间)
                    Thread.sleep(new Random().nextInt(3000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t同学写完,离开教室");
                // 上交试卷给老师(走一个,计数减少一个)
                countDownLatch.countDown();
            }, i + "号考生").start();
        }

        // 主线程相当于老师,需要等所有的人交卷,才能离开(阻塞当前线程,等待所有线程完成任务,即 countDown)
        countDownLatch.await();

        Thread.currentThread().setName("老师");
        System.out.println(Thread.currentThread().getName() + "\t收齐试卷,关门走人");
    }
}

输出结果

在这里插入图片描述


二、CyclicBarrier

CyclicBarrier如同游戏匹配,不凑齐人数,就一直在匹配界面,达到指定人数后才能开始对战

代码如下(示例)

public class Test {
    public static void main(String[] args) throws InterruptedException {
        // CyclicBarrier 指定值达到 0,发射

        // 需要十个人才能开始游戏,(指定个数,之后不能改变,满足条件后,自动执行 Runnable 方法)
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10, () -> {
            System.out.println("十个人已经全部确认,开始游戏");
        });

        for (int i = 1; i <= 10; i++) {
            final int tmpInt = i;
            new Thread(() -> {
                try {
                    // 模拟玩家匹配时间
                    Thread.sleep(new Random().nextInt(3000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t已经确认");
                try {
                    // 等待其他玩家准备(阻塞等待,等待人数减 1,减到 0,就发车)
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, tmpInt + "号玩家").start();
        }

    }
}

输出结果
在这里插入图片描述


三、Semaphore

Semaphore如同一个停车场,里面的车位数是固定的,当停满车后,必须有车出来才能再进

Semaphore 主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。
涉及到并发就有有两种模式:

  1. 非公平(谁抢到是谁的),默认是非公平的
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }
  1. 公平(先来后到),当 fair 为 true 是公平的
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

代码如下(示例)

public class Test {
    public static void main(String[] args) throws InterruptedException {
        // 一共 3 个停车位(资源数开始时固定)
        Semaphore semaphore = new Semaphore(3);// 默认非公平(抢占式)

        // 模拟 6 辆汽车要停车
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    // 询问还有没有停车位,有就进去,没有等待(获得资源)
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t抢到车位");
                    // 模拟停车时间
                    Thread.sleep(new Random().nextInt(3000));
                    System.out.println(Thread.currentThread().getName() + "\t事情办完,离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // 办完事情,开车离开(释放资源)
                    semaphore.release();
                }
            }, i + "号车主").start();
        }
    }
}

输出结果
在这里插入图片描述


四、Phaser

Phaser是JDK 7新增的一个同步辅助类,它可以实现CyclicBarrier和CountDownLatch类似的功能,而且它支持对任务的动态调整,并支持分层结构来达到更高的吞吐量。

CountDownLatch 和 CyclicBarrier 在最初就固定了线程的数量,而且中途不可改变,当完成指定的任务后,就不能再次使用,Phaser 就解决了该问题。

class player implements Runnable {

    private final Phaser phaser;

    player(Phaser phaser) {
        this.phaser = phaser;
    }

    @Override
    public void run() {
        try {
            // 第一阶段——确定参赛的运动员人数(等待创建好所有线程再开始)
            phaser.arriveAndAwaitAdvance();

            // 第二阶段——等待所有选手都做好准备,发令枪再开始
            Thread.sleep(new Random().nextInt(3000));// 模拟热身准备
            System.out.println(Thread.currentThread().getName() + "号运动员准备完毕");
            phaser.arriveAndAwaitAdvance();

            // 第三阶段——所有运动员开始跑步
            Thread.sleep(new Random().nextInt(3000));// 模拟跑步时间
            System.out.println(Thread.currentThread().getName() + "号运动员冲线!");

            // 冲线后结束(线程下线注销)
            phaser.arriveAndDeregister();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {

        // 模拟了 100 米赛跑,10 名运动员,只等裁判一声令下。当所有人都到达终点时,比赛结束。
        // 设置初始的注册人数(1 个裁判)
        final Phaser phaser = new Phaser(1);
        // 十名运动员
        for (int index = 0; index < 10; index++) {
            // 每个运动员都注册到其中,即确定参加比赛(动态增加,复用)
            phaser.register();
            new Thread(new player(phaser), index + "号运动员").start();
        }
        System.out.println("比赛开始");
        // 裁判下线,注销当前线程,比赛开始
        phaser.arriveAndDeregister();
        // 所有运动员是否到达终点,没有就一直等待
        while (!phaser.isTerminated()) {
        }
        System.out.println("所有运动员到达终点,比赛结束");

    }
}

输出结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1352793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gitee创建仓库

描述 本文章记录了怎么在gitee上创建项目&#xff0c;以及使用vscode提代码到远程呢个仓库&#xff0c;如何创建一个新分支&#xff0c;并将新分支提交到远程仓库。 1、创建远程仓库 在创建远程仓库之前要先进行ssh密钥的设置 &#xff08;1&#xff09;打开黑窗口&#xff…

NSSCTF 简单包含

开启环境: 使用POST传flag&#xff0c;flag目录/var/www/html/flag.php 先使用post来尝试读取该flag.php 没反应: 查看一下源码index.php&#xff0c;看有什么条件 base64解密: <?php$path $_POST["flag"];if (strlen(file_get_contents(php://input)) <…

SSH

简介 SSH&#xff1a;Secure Shell Protocol&#xff0c;安全的远程登录&#xff0c;实现加密通信&#xff0c;替代传统telnet协议。 端口&#xff1a;22/tcp 软件实现&#xff1a; OpenSSH&#xff1a;ssh协议的开源实现&#xff0c;CentOS默认安装Dropbear&#xff1a;另…

Socket closed 异常解决方案:如何解决 JMeter 压测中的问题

问题描述 JMeter 压测时会报 java.net.SocketException: Socket closed java.net.SocketException: Socket closed at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.ne…

CMake入门教程【核心篇】宏模板(macro)

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1. 定义宏1.1 基本语…

红日靶场-3

目录 前言 外网渗透 外网渗透打点 1、arp 2、nmap 3、nikto 4、whatweb 5、gobuster 6、dirsearch CMS 1、主页内容 2、/configuration.php~ 目录 3、/administrator 目录 4、Joomla!_version探测 5、joomlascan python脚本 6、joomscan perl脚本 MySQL 1、远…

bootstrap5实现通用果蔬网站 FoodMart页面模板

一、需求分析 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。它将不同种类的新鲜水果、蔬菜、干果、坚果等聚集在一起&#xff0c;为消费者提供方便、快捷的购物渠道。通用果蔬网站的作用主要包括以下几个方面&#xff1a; 商品展示和销售&#xff1a;通用果蔬网…

[DevOps-01] DevOps介绍

一、简要描述 DevOps&#xff1a;Development & Operations的缩写&#xff0c;也就是开发&运维 DevOps是一个不断提高效率并且持续不断工作的过程。 核心&#xff1a;简化Dev和Ops团队之间的流程&#xff0c;使整体软件开发过程更快速。 DevOps定义&#xff1a; DevOps…

4462 4.曙曙献爱心

#include<bits/stdc.h> using namespace std; int n,m,k; int a[1001]; int s[1001]; int f[1001][1001];//f[i][j]&#xff0c;i个警察&#xff0c;j个点&#xff0c;能管理的最大人数 int main(){cin>>n>>m>>k;for(int i1;i<n;i){cin>>a[i…

Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API

笔者曾经写过 ChatGPT OpenAI API请求限制 尝试解决 Account deactivated. Please contact us through our help center at help.openai.com if you need assistance. 结果如何&#xff1f; 没有啥用。目前发现一条曲线救国的方案。 1. 在官方 openai 库中使用 此处为最新Op…

什么是Maven ??? (以及关于依赖,中央仓库,国内源)

文章目录 什么是 Maven创建第一个 Maven 项目依赖管理Maven 的仓库Maven 如何设置国内源 什么是 Maven Maven &#xff1a;用于构建和管理任何基于java的项目的工具。**说白了就是管理 Java项目 的工具。**我们希望我们已经创建了一些东西&#xff0c;可以使Java开发人员的日常…

大一C语言基础知识点圈画1(结构体,共用体指针,数组字符串)

是所有成员占内存的总和吗&#xff1f; 不是&#xff0c; 非所有成员变量的内存总和

机器学习常用算法模型总结

文章目录 1.基础篇&#xff1a;了解机器学习1.1 什么是机器学习1.2 机器学习的场景1.2.1 模式识别1.2.2 数据挖掘1.2.3 统计学习1.2.4 自然语言处理1.2.5 计算机视觉1.2.6 语音识别 1.3 机器学习与深度学习1.4 机器学习和人工智能1.5 机器学习的数学基础特征值和特征向量的定义…

视频剪辑方法:掌握视频嵌套合并技术,释放无限创意

随着数字媒体的普及&#xff0c;视频剪辑已是创意表达的重要技巧。通过掌握视频嵌套合并技术&#xff0c;可以将多个视频片段融合在一起&#xff0c;创造出独特的视觉效果和故事叙述。现在一起看云炫AI智剪批量剪辑视频嵌套合并方法&#xff0c;释放无限创意。 准备视频素材&a…

知识库:提升客服效率的利器

相信大家都有过这样的经历&#xff1a;在需要帮助或解决问题时&#xff0c;与客服沟通却遇到了冗长的等待时间、低效的回答和重复的解决方案。这些问题不仅令人沮丧&#xff0c;也给企业带来了巨大的挑战。然而&#xff0c;随着技术的发展&#xff0c;客服系统中的知识库正逐渐…

sqlserver根据分组的内容分别查询出匹配的一条信息

需求场景&#xff1a; 我写了条分组语句&#xff0c; select name from car_machine_command group by name 然后该表有很多条相关的数据&#xff0c;我只想拿各个分组的一条数据看看即可 解决&#xff1a;可以使用窗口函数&#xff08;Window Function&#xff09;和 ROW_NU…

电磁波的信号加载说明

电磁波的信号加载电磁波(Electromagnetic wave)是由同相振荡 且互相垂直的电场与磁场在空间中衍生发射的振荡粒子波&#xff0c;是以波动的形式传播的电磁场&#xff0c;具有波粒二象性&#xff0c;其粒子形态称为光子&#xff0c;电磁波与光子不是非黑即白的关系&#xff0c;而…

【算法系列 | 11】深入解析查找算法之—插值查找

序言 心若有阳光&#xff0c;你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏&#xff0c;希望能帮助大家很好的了解算法。主要深入解析每个算法&#xff0c;从概念到示例。 我们一起努力&#xff0c;成为更好的自己&#xff01; 今天第11讲&#xff0c;讲…

kbdnso.dll文件缺失,软件或游戏报错的快速修复方法

很多小伙伴遇到电脑报错&#xff0c;提示“kbdnso.dll文件缺失&#xff0c;程序无法启动执行”时&#xff0c;不知道应该怎样处理&#xff0c;还以为是程序出现了问题&#xff0c;想卸载重装。 首先&#xff0c;先要了解“kbdnso.dll文件”是什么&#xff1f; kbdnso.dll是Win…

拒绝纸张浪费,Paperless-ngx开源文档管理系统将纸质版转换成可搜索的电子版档案

GitHub&#xff1a;GitHub - paperless-ngx/paperless-ngx: A community-supported supercharged version of paperless: scan, index and archive all your physical documents 在线演示&#xff1a;https://demo.paperless-ngx.com 官网&#xff1a;https://docs.paperless-n…