欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線程中的Phaser使用解析

 更新時間:2023年11月30日 08:34:09   作者:MC-閏土  
這篇文章主要介紹了Java多線程中的Phaser使用解析,java多線程技術(shù)提供了Phaser工具類,Phaser表示“階段器”,用來解決控制多個線程分階段共同完成任務(wù)的情景問題,其作用相比CountDownLatch和CyclicBarrier更加靈活,需要的朋友可以參考下

問題描述

java多線程技術(shù)提供了Phaser工具類,Phaser表示“階段器”,用來解決控制多個線程分階段共同完成任務(wù)的情景問題。

其作用相比CountDownLatch和CyclicBarrier更加靈活,例如有這樣的一個題目:

5個學(xué)生一起參加考試,一共有三道題,要求所有學(xué)生到齊才能開始考試,全部同學(xué)都做完第一題,學(xué)生才能繼續(xù)做第二題,全部學(xué)生做完了第二題,才能做第三題,所有學(xué)生都做完的第三題,考試才結(jié)束。

分析這個題目:這是一個多線程(5個學(xué)生)分階段問題(考試考試、第一題做完、第二題做完、第三題做完),所以很適合用Phaser解決這個問題。

實現(xiàn)代碼

import java.util.concurrent.Phaser;
 
/***
 *  下面說說Phaser的高級用法,在Phaser內(nèi)有2個重要狀態(tài),分別是phase和party。
 *  phase就是階段,初值為0,當(dāng)所有的線程執(zhí)行完本輪任務(wù),同時開始下一輪任務(wù)時,
 *  意味著當(dāng)前階段已結(jié)束,進入到下一階段,phase的值自動加1。party就是線程,
 *  party=4就意味著Phaser對象當(dāng)前管理著4個線程。Phaser還有一個重要的方法經(jīng)常需要被重載,
 *  那就是boolean onAdvance(int phase, int registeredParties)方法。此方法有2個作用:
 *  1、當(dāng)每一個階段執(zhí)行完畢,此方法會被自動調(diào)用,因此,重載此方法寫入的代碼會在每個階段執(zhí)行完畢時執(zhí)行,
 *  相當(dāng)于CyclicBarrier的barrierAction。
 *  2、當(dāng)此方法返回true時,意味著Phaser被終止,因此可以巧妙的設(shè)置此方法的返回值來終止所有線程。
 * @author liujun
 */
public class MyPhaser extends Phaser {
 
	@Override
	protected boolean onAdvance(int phase, int registeredParties) {	//在每個階段執(zhí)行完成后回調(diào)的方法
		
		switch (phase) {
		case 0:
			return studentArrived();
		case 1:
			return finishFirstExercise();
		case 2:
			return finishSecondExercise();
		case 3:
			return finishExam();
		default:
			return true;
		}
		
	}
	
	private boolean studentArrived(){
		System.out.println("學(xué)生準(zhǔn)備好了,學(xué)生人數(shù):"+getRegisteredParties());
		return false;
	}
	
	private boolean finishFirstExercise(){
		System.out.println("第一題所有學(xué)生做完");
		return false;
	}
	
	private boolean finishSecondExercise(){
		System.out.println("第二題所有學(xué)生做完");
		return false;
	}
	
	private boolean finishExam(){
		System.out.println("第三題所有學(xué)生做完,結(jié)束考試");
		return true;
	}
	
}
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
 
public class StudentTask implements Runnable {
 
	private Phaser phaser;
	
	public StudentTask(Phaser phaser) {
		this.phaser = phaser;
	}
 
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"到達考試");
		phaser.arriveAndAwaitAdvance();
		
		System.out.println(Thread.currentThread().getName()+"做第1題時間...");
		doExercise1();
		System.out.println(Thread.currentThread().getName()+"做第1題完成...");
		phaser.arriveAndAwaitAdvance();
		
		System.out.println(Thread.currentThread().getName()+"做第2題時間...");
		doExercise2();
		System.out.println(Thread.currentThread().getName()+"做第2題完成...");
		phaser.arriveAndAwaitAdvance();
		
		System.out.println(Thread.currentThread().getName()+"做第3題時間...");
		doExercise3();
		System.out.println(Thread.currentThread().getName()+"做第3題完成...");
		phaser.arriveAndAwaitAdvance();
	}
 
	private void doExercise1() {
		long duration = (long)(Math.random()*10);
		try {
			TimeUnit.SECONDS.sleep(duration);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private void doExercise2() {
		long duration = (long)(Math.random()*10);
		try {
			TimeUnit.SECONDS.sleep(duration);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private void doExercise3() {
		long duration = (long)(Math.random()*10);
		try {
			TimeUnit.SECONDS.sleep(duration);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}
/**
 * 題目:5個學(xué)生參加考試,一共有三道題,要求所有學(xué)生到齊才能開始考試
 * ,全部做完第一題,才能繼續(xù)做第二題,后面類似。
 * 
 * Phaser有phase和party兩個重要狀態(tài),
 * phase表示階段,party表示每個階段的線程個數(shù),
 * 只有每個線程都執(zhí)行了phaser.arriveAndAwaitAdvance();
 * 才會進入下一個階段,否則阻塞等待。
 * 例如題目中5個學(xué)生(線程)都條用phaser.arriveAndAwaitAdvance();就進入下一題
 * @author liujun
 */
public class Main {
 
	public static void main(String[] args) {
		MyPhaser phaser = new MyPhaser();
		StudentTask[] studentTask = new StudentTask[5];
		for (int i = 0; i < studentTask.length; i++) {
			studentTask[i] = new StudentTask(phaser);
			phaser.register();	//注冊一次表示phaser維護的線程個數(shù)
		}
		
		Thread[] threads = new Thread[studentTask.length];
		for (int i = 0; i < studentTask.length; i++) {
			threads[i] = new Thread(studentTask[i], "Student "+i);
			threads[i].start();
		}
		
		//等待所有線程執(zhí)行結(jié)束
		for (int i = 0; i < studentTask.length; i++) {
			try {
				threads[i].join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println("Phaser has finished:"+phaser.isTerminated());
		
	}
	
}

結(jié)果

Student 0到達考試
Student 1到達考試
Student 4到達考試
Student 2到達考試
Student 3到達考試
學(xué)生準(zhǔn)備好了5
Student 2做第1題時間...
Student 0做第1題時間...
Student 1做第1題時間...
Student 4做第1題時間...
Student 3做第1題時間...
Student 2做第1題完成...
Student 3做第1題完成...
Student 1做第1題完成...
Student 0做第1題完成...
Student 4做第1題完成...
第一題所有學(xué)生做完
Student 3做第2題時間...
Student 0做第2題時間...
Student 4做第2題時間...
Student 1做第2題時間...
Student 2做第2題時間...
Student 3做第2題完成...
Student 2做第2題完成...
Stud ent 0做第2題完成...
Student 1做第2題完成...
Student 4做第2題完成...
第二題所有學(xué)生做完
Student 0做第3題時間...
Student 3做第3題時間...
Student 2做第3題時間...
Student 4做第3題時間...
Student 1做第3題時間...
Student 1做第3題完成...
Student 0做第3題完成...
Student 2做第3題完成...
Student 3做第3題完成...
Student 4做第3題完成...
第三題所有學(xué)生做完,結(jié)束考試
Phaser has finished:true

到此這篇關(guān)于Java多線程中的Phaser使用解析的文章就介紹到這了,更多相關(guān)Java多線程中的Phaser內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java Matcher匹配頭尾截取替換字符串的案例

    java Matcher匹配頭尾截取替換字符串的案例

    這篇文章主要介紹了java Matcher匹配頭尾截取替換字符串的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • MyBatisPlus中批量插入之如何通過開啟rewriteBatchedStatements=true

    MyBatisPlus中批量插入之如何通過開啟rewriteBatchedStatements=true

    這篇文章主要介紹了MyBatisPlus中批量插入之如何通過開啟rewriteBatchedStatements=true問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • java使用HashMap實現(xiàn)斗地主(有序版)

    java使用HashMap實現(xiàn)斗地主(有序版)

    這篇文章主要為大家詳細介紹了java使用ArrayList實現(xiàn)斗地主游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 一文帶你了解Java萬物之基之Object類

    一文帶你了解Java萬物之基之Object類

    Java是一門天然的面向?qū)ο蟮恼Z言。而所有我們手動創(chuàng)造出來的類,都繼承于同一個類,即Object類。本文將通過示例為大家詳細介紹一下Java中的Object類,需要的可以參考一下
    2022-03-03
  • Spring Boot啟動端口修改方法

    Spring Boot啟動端口修改方法

    spring boot是個好東西,可以不用容器直接在main方法中啟動,而且無需配置文件,方便快速搭建環(huán)境。下面通過本文給大家分享Spring Boot修改啟動端口的方法,感興趣的的朋友一起看看吧
    2017-07-07
  • spring?boot自動裝配之@ComponentScan注解用法詳解

    spring?boot自動裝配之@ComponentScan注解用法詳解

    @ComponentScan的作用就是根據(jù)定義的掃描路徑,把符合掃描規(guī)則的類裝配到spring容器中,下面這篇文章主要給大家介紹了關(guān)于spring?boot自動裝配之@ComponentScan注解用法的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 只用400行Java代碼就能實現(xiàn)的飛翔的小鳥游戲

    只用400行Java代碼就能實現(xiàn)的飛翔的小鳥游戲

    今天給大家?guī)淼氖顷P(guān)于Java實戰(zhàn)的相關(guān)知識,文章圍繞著只用400行Java代碼就能實現(xiàn)的飛翔的小鳥游戲展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Java計時器StopWatch實現(xiàn)方法代碼實例

    Java計時器StopWatch實現(xiàn)方法代碼實例

    這篇文章主要介紹了Java計時器StopWatch實現(xiàn)方法代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • springboot如何獲取登錄用戶的個人信息

    springboot如何獲取登錄用戶的個人信息

    在Spring Boot中,獲取登錄用戶的個人信息通常需要使用Spring Security框架來進行身份認證和授權(quán),這篇文章主要介紹了springboot獲取登錄用戶的個人信息,需要的朋友可以參考下
    2023-05-05
  • Java任意長度byte數(shù)組轉(zhuǎn)換為int數(shù)組的方法

    Java任意長度byte數(shù)組轉(zhuǎn)換為int數(shù)組的方法

    這篇文章主要給大家介紹了關(guān)于Java任意長度byte數(shù)組轉(zhuǎn)換為int數(shù)組的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論