Java 并发编程 (三)Phaser

news2024/12/26 11:54:46

#Phaser

功能介绍

CyclicBarrier 解决了 CountDownLatch的缺点,但是其本身也仍然具备一定的缺陷,比如不可以动态添加parties 调用一次await 仅占用1个parties

public class MyPhaser {

    private Phaser phaser = new Phaser(3);

    public void testA(){
        System.out.println(Thread.currentThread().getName() + " 1Begin " + System.currentTimeMillis());
        phaser.arriveAndAwaitAdvance();
        System.out.println(Thread.currentThread().getName() + " 1End " + System.currentTimeMillis());


        System.out.println(Thread.currentThread().getName() + " 2Begin " + System.currentTimeMillis());
        phaser.arriveAndAwaitAdvance();
        System.out.println(Thread.currentThread().getName() + " 2End " + System.currentTimeMillis());

    }

    public void testB(){
        try {
            System.out.println(Thread.currentThread().getName() + " 1Begin " + System.currentTimeMillis());
            Thread.sleep(5000);
            phaser.arriveAndAwaitAdvance();
            System.out.println(Thread.currentThread().getName() + " 1End " + System.currentTimeMillis());

            System.out.println(Thread.currentThread().getName() + " 2Begin " + System.currentTimeMillis());
            Thread.sleep(5000);
            phaser.arriveAndAwaitAdvance();
            System.out.println(Thread.currentThread().getName() + " 2End " + System.currentTimeMillis());

        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MyPhaser myPhaser = new MyPhaser();
        MyThread myThread = new MyThread(myPhaser);
        myThread.setName("A");
        myThread.start();

        MyThread myThread1 = new MyThread(myPhaser);
        myThread1.setName("B");
        myThread1.start();

        MyThreadC myThread2 = new MyThreadC(myPhaser);
        myThread2.setName("C");
        myThread2.start();

    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public static class MyThread extends Thread{

        private MyPhaser myPhaser;
        @Override
        public void run() {
            myPhaser.testA();
        }
    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public static class MyThreadC extends Thread{

        private MyPhaser myPhaser;
        @Override
        public void run() {
            myPhaser.testB();
        }
    }

}

在这里插入图片描述

使用 arriveAndAwaitAdvance方法再遇到计数不足时会导致进程被阻塞 可以使用 arriveAndDeregister 在线程结束时使partie减一。

只需改动下 testB方法即可验证

    public void testB(){
        try {
            System.out.println(Thread.currentThread().getName() + " 1Begin " + System.currentTimeMillis());
            Thread.sleep(5000);
            phaser.arriveAndAwaitAdvance();
            System.out.println(Thread.currentThread().getName() + " 1End " + System.currentTimeMillis());

        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

getPhase() 可以获取当前已经到达多少个屏障

在通过新的 屏障时被调用 onAdvance
返回true不等待了, Phaser 为无效/销毁状态
返回false Phaser 继续工作

    private Phaser phaser = new Phaser(3){
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            System.out.println(phase + " " + registeredParties);
            System.out.println("onAdvance used");
            //返回true不等待了, Phaser 为无效/销毁状态
            //返回false Phaser 继续工作
            return true;
        }
    };

getRegisteredParties() 获取注册的parties
register() 动态添加一个parties
bulkRegister(n) 动态批量添加 parties
getArrivedParties() 获取已经被使用的parties
getUnarrivedParties() 获取未使用的parties
arrive() 使parties值加1,但不再屏障处等待,继续向下运行。
Pharse 也具备计数重制功能

public static void main(String[] args) {
        Phaser phaser = new Phaser(2);
        System.out.println(1 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();

        System.out.println(2 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();

        System.out.println(3 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();

        System.out.println(4 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();

        System.out.println(5 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();
    }

在这里插入图片描述
如上,每次调用arrive() getArrivedParties+1 切 每次达到2 都会重制计数

awaitAdvance(n) 如果 n == getPhase 则阻塞 且 不可被 interrupted

    public static void main(String[] args) {
        Phaser phaser = new Phaser(2);
        System.out.println(1 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();
        phaser.awaitAdvance(0);
        System.out.println("run");
        System.out.println(2 + " getPhase: " + phaser.getPhase() + " getArrivedParties: " + phaser.getArrivedParties() );
        phaser.arrive();
    }

2 并未执行
在这里插入图片描述

awaitAdvanceInterruptibly() 与 awaitAdvance() 相反可以被中断。
awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) 当屏障达到 phase时 如果超过 timeout 时间没有变化测抛出异常
forceTermination() 将屏障取消 并且 getPhase = Integer.MIN_VALUE
isTerminated() 判断Phase 是否已经被销毁

总结:

类Phaser提供了动态增减parties计数的能力, 比CyclicBarrier 更方便。并且支持在指定屏障处等待,也支持在等待时中断或非中断等功能。相比CyclicBarrier 更建议使用Phase

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

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

相关文章

微信过期文件怎么找回?2个方法,轻松解决

现在很多小伙伴都喜欢使用微信发送文字、图片、语音、照片、文件等内容给对方。可是在其中,文件内容比较特殊。如果没有及时进行查看,过了一段时间就会变成过期文件,无法再进行查看了。微信过期文件怎么找回?今天小编分享2个简单好…

微型消防站一体化指挥作战解决方案

一、政策要求 近年政府对社区微型消防站提出了新的建设要求: 1、 大力发展多种形式消防队伍,逐步加强现役消防力量建设,发展政府专职消防队,企业事业单位专职消防队和志愿消防队。 2、 明确城市消防安全布局和公共消防设施的消…

vue 可视化表单设计器 自定义组件

有一款基于vue的可视化表单编辑器,直接双击或者拖拽组件,便可以创建一个表单,非常方便。今天为大家介绍这款编辑器: 官方地址:Variant Form - 可视化低代码表单 github地址:https://github.com/vform666/…

Redshift渲染器为什么这么受欢迎?

Redshift是用于高质量制作工作的渲染器 。它是很快的渲染引擎,并且可以很好地与许多第三方插件配合使用。在本文中,让我们深入了解Redshift的更多细节。什么是 Redshift 及其工作原理?Redshift 是一种有偏见的 GPU 渲染引擎,它支持…

【回答问题】ChatGPT上线了!给我推荐20个比较流行的OCR模型

给我推荐20个比较流行的OCR模型 好的,以下是我为你推荐的 20 个比较流行的 OCR 模型。 Tesseract CuneiForm Ocrad GOCR OCRopus OCR-ICR Ocropy Ocrad.js Ocracoke Ocralysis Ocrinum Ocrmypdf Ocrsaurus Ocrdroid Ocr-textscan Ocrfeeder Ocrmypicture Ocrus Oc…

RHCE-chrony服务部署

目录 要求: 思路: 配置过程: a: 1.开启两台服务器,开启chrony服务。 2.部署chrony服务 查看chrony服务状态 b: 区别: 配置过程: 修改完配置后,重启chrony服务 查看chrony状态: 小结一…

element-ui 多选框和级联选择的部分bug以及解决方法

前言 最近在开发一款使用了 element-ui 的低代码设计器,在开发的过程当中碰到了一些关于 element-ui 组件本身不合理的地方,并且在百度的基础上自己去阅读了一下 element-ui 的源码,也找出了这些问题的一个解决方案,下面就来看一…

steam搬砖是什么?怎么做呀?

steam平台是什么?它是国外一个集全球大部分网游于一体的游戏平台,玩过绝地求生端游(吃鸡),csgo的朋友,对它都不陌生,就像国内的Wegame一样,现在玩英雄联盟的,都是通过Weg…

排序算法之冒泡算法

目录 排序算法介绍 冒泡排序 算法流程 算法实现 python C 排序算法介绍 《Hello算法》是GitHub上一个开源书籍,对新手友好,有大量的动态图,很适合算法初学者自主学习入门。而我则是正式学习算法,以这本书为参考&#xff0c…

返回数组所有元素中或每行(列)中,最小值的位置(位置号从0开始):argmin()函数

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 返回数组所有元素中或每行(列)中 最小值的位置(位置号从0开始) argmin()函数 选择题 下列说法错误的是? import numpy as np a np.array([[10,20,30,40],[15,20,25…

Electron 企业级应用开发实战(二)

这一讲会重点介绍如何集成 Node.js、使用 preload 脚本、进程间双向通信、上下文隔离等,为大家揭开 Electron 更强大的能力。 集成 Node.js 企业级桌面应用的资源都是本地化的,离线也能使用,所以需要把 html、js、css 这些资源都打包进去&a…

独立光伏-电池-柴油发电机组的能源管理系统的主干网研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

ESPI3接收机

18320918653 ESPI3 ESPI3|R&S ESPI3|二手EMI接收机|EMI预认证测试接收机|罗德与施瓦茨|EMC接收机|9KHz至3GHz品 牌:德国罗德与施瓦茨 | R&S | Rohde&Schwarz处于预认证级别的 R&S ESPI测试接收机有两种型号, 集成了罗德与施瓦茨公司认证级EMI测试…

springboot:除了OpenOffice还可以用它轻松实现文档在线预览功能【附带源码】

0. 引言 我们在项目中常常需要实现文档在线预览的功能,而文档种类繁多,除了pdf,还有word、text、excel、甚至还有mp3,mp4等多媒体文件。常用的手段是通过OpenOffice来将文档转换为pdf实现预览,本期我们就来看如何通过kkFileView实…

rabbitmq基础10——消息追踪、Shovel插件的web端使用和命令使用

文章目录一、消息追踪1.1 Firehose功能1.1.1 开启与关闭1.1.2 测试1.1.3 总结1.2 rabbitmq_tracing 插件1.2.1 定义trace规则1.2.2 测试1.2.2.1 与Firehose之间的优先级二、Shovel插件2.1 实现原理2.1.1 从队列到交换器2.1.2 从队列到队列2.1.3 交换器到交换器2.2 Shovel 插件使…

大小端转换

一、名词解释首先解释一下大端模式和小端模式。小端模式,也叫小端存储:Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。大端模式,也叫大端存储:Big-Endian就是高位字节排放在内存的低地…

2022年度技术总结

2022 年度总结 本年收获 计算机网络 2022年2月,系统学习巩固了计算机网络课程(本科),基本的七层模式,四层模式,重点是与前端开发相关的 TCP UDP HTTP HTTPS 等协议。 现在有一个整体的认识:…

@Transactional事务处理解决方案的看法

Transactional事务处理解决方案的看法前言一.声明式事务二.编程式事务三.事务粒度优化方法四.缓存和事务的一致性五.介绍--延时双删总结前言 提示:这里可以添加本文要记录的大概内容: 本文就是了解一下声明式事务和编程式事务的优缺点和事务一致性的一…

怎样阅读NLP论文

经典的论文也是需要读的。并不是所有的论文都值得细读。论文不是从头赶着朝下读。 目录收集和组织论文收集组织1.通过会议的方式分类2.是否是arXiv上的文章分类(preprint or not)3.根据问题(推荐),方法和数据集分类选择…

Ka波段卫星通信小尺寸无线电设计

传统Ka波段地面站卫星通信系统依赖于室内到室外配置。室外单元包含天线和块下变频接收机,接收机输出L波段的模拟信号。该信号随后被传送到室内单元,室内单元包含滤波、数字化和处理系统。Ka波段的干扰信号通常较少,因此室外单元的主要任务是以…