【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
Phaser是一个类型于CountDownLatch和CyclicBarrier的类,但是要比前两个灵活许多,它可以动态变化增加
先说说使用核心:那就是跟CyclicBarrier类似,也是等待的线程数到达一定值时所有线程才可以往下走,但是要比CyclicBarrier更加灵活,它可以动态的控制这个数值。
然后看看使用的核心方法:
跟CyclicBarrier一样可以初始化的时候指定长度,也可以不指定长度
Phaser phaser = new Phaser(); Phaser phaser = new Phaser(1);
通过arriveAndAwaitAdvance()来等待下一阶段的运行
register()和arriveAndDeregister() 这两个方法是用来增加和减少注册量,这个注册量就相当于CyclicBarrier的固定数值。bulkResgister(int) 这方法是批量增加线程数
getPhaser() 可以获取当前是第几阶段,通俗点说就是当前是第几次等待
getArrivedParties()和getUnarrivedParties()这两个方法可以获取到达和未到达该屏障的线程数
isTerminated() 此方法是判断Phaser有没有结束,意思就是注册数是不是为0
arrive() 这个方法就是不等待屏障,直接往下执行
getRegisteredParties() 获取已经注册的线程数
上面就是常用的几个方法
使用样例:
package com.test; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.concurrent.Phaser; import java.util.concurrent.TimeUnit; /** * 查找文件夹下所有log结尾的文件 并且是24小时内修改过的,分为三个阶段 * 1.找到所有log结尾的文件 * 2.找到24小时内修改过的文件 * 3.展示 */ public class PhaserTest { public static void main(String[] args) { Phaser phaser = new Phaser(); Deal system=new Deal("C:\\Windows", "log", phaser); Deal apps=new Deal("C:\\Program Files", "log", phaser); Deal documents=new Deal("C:\\Documents And Settings", "log", phaser); Thread systemThread=new Thread(system, "system"); systemThread.start(); Thread appsThread=new Thread(apps, "apps"); appsThread.start(); Thread documentsThread=new Thread(documents, "documents"); documentsThread.start(); try { systemThread.join(); appsThread.join(); documentsThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("everything is over"); } static class Deal implements Runnable { String fileDir; String end; Phaser phaser; public Deal(String fileDir, String end, Phaser phaser) { this.fileDir = fileDir; this.end = end; this.phaser = phaser; phaser.register(); } @Override public void run() { //此阶段等所有线程启动 System.out.println("当前阶段:"+phaser.getPhase()); phaser.arriveAndAwaitAdvance(); System.out.println("移位器是否结束"+ phaser.isTerminated()); System.out.println("注册的线程数"+ phaser.getRegisteredParties()); findByEnd(); if (endList.size() == 0) { System.out.println(Thread.currentThread().getName()+" endList为空 over"); phaser.arriveAndDeregister(); return; } System.out.println("读取结尾文件夹成功-----"+fileDir); //此阶段等所有线程过滤结尾 System.out.println("当前阶段:"+phaser.getPhase()); phaser.arriveAndAwaitAdvance(); findByTime(); if (timeList.size() == 0) { System.out.println(Thread.currentThread().getName()+" timeList over"); phaser.arriveAndDeregister(); return; } System.out.println("当前阶段:"+phaser.getPhase()); //此阶段等待所有线程过滤时间 System.out.println("当前到达屏障的数量:"+phaser.getArrivedParties()); System.out.println("当前未到达屏障的数量:"+phaser.getUnarrivedParties()); phaser.arriveAndAwaitAdvance(); phaser.arriveAndDeregister(); showList(); System.out.println(Thread.currentThread().getName()+" over"); System.out.println("移位器是否结束"+ phaser.isTerminated()); } //存放结尾集合 private ArrayList<String> endList = new ArrayList<>(); void findByEnd() { File dir = new File(fileDir); if (dir.exists() && dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) for (File file : files) { String name = file.getName(); if (name.endsWith(end)) { endList.add(file.getAbsolutePath()); } } } } //存放时间类 private ArrayList<String> timeList = new ArrayList<>(); void findByTime() { for(int a =0 ;a<endList.size();a++) { String fileName = endList.get(a); File file = new File(fileName); long l = new Date().getTime() - file.lastModified(); if (l < TimeUnit.MICROSECONDS.convert(1, TimeUnit.DAYS)) { timeList.add(fileName); } } } void showList(){ for(int a =0 ;a<timeList.size();a++) { System.out.println("文件夹下:" + fileDir + "文件:" + timeList.get(a)); } } } }
来源:oschina
链接:https://my.oschina.net/u/4291478/blog/3153231