Future.get方法ブロック問題のスレッドプールソリューション、CompletableFuture

1、未来

将来のモデルは、一般的にマルチスレッドデザインパターンを設計するために使用されています。私は将来的に投入されたジョブを、持っている私は、このタスクを完了するために、未来:将来モデルが理解することができます。私自身の中にあなたがやりたいことができます。しばらくすると、私はそこに便利な将来の結果を削除することができます。
:将来は3つの機能を提供し
、タスクが完了したかどうかを判断するため
の作業を中断することができ
、タスクの実行結果を得ることができる
方法がブロックされていないスレッドプールにタスクを提出する方法を提出し、複数のタスクを提出提出する際Future.get方法は、ブロックする方法であり、すべてのタスクが完了した後にのみ、ご注文を提出する作業に応じて得られる結果を返すためにgetを使用することができ、一般的な結果を得るfuture.get使用が終了した後、最初にすべてのタスクの実行が完了したかどうかを判断する使用future.isDoneに必要とされます。(また、待ち時間に無制限の時間を防ぐためにタイムアウトを設定してもらう(長いタイムアウト、TimeUnitでユニット)メソッドを使用することができます)
プログラム3つの段階:1. 2. 3.収集他のものを処理するマルチスレッド、将来の結果をマルチスレッド化)(円形または使用isDone、将来のリターンの結果を待っている)あなたは、需要の非同期実行結果へのアクセスを実現することができますが、それはの通知、または使用のブロック、場所future.get(のためのメカニズムを提供していませんが、それは同期動作でありますお問い合わせ裁判官が将来が完了すると、それがCPUリソースを消費します。
溶液:(タスク順序のタスク完了の結果に応じて取得した)CompletionServiceとCompletableFuture

使用前に2、CompletionService java1.8最善の方法、

結果は、順序を取得するタスクを完了するためにタスクに応じて達成することができます。

public class TestCompletionService {
	private static final String commandstr01 = "hahah";
	private static final String commandstr02 = "hahah";
	
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//1、创建一个线程池
		ExecutorService executorService = Executors.newCachedThreadPool();
		
		CompletionService<String> completionService = new ExecutorCompletionService<String>(executorService);
		
		completionService.submit(new MyThreadt33(commandstr01));
		completionService.submit(new MyThreadt44(commandstr01));
			
		executorService.shutdown();
		
		System.out.println(completionService.take().get());
		System.out.println(completionService.take().get());
	}
}
 
class MyThreadt33 implements Callable<String>{
	private String commandstr;          // 要运行的mingling
	public MyThreadt33(String commandstr) {
		this.commandstr = commandstr;
	}
	@Override
	public String call() throws Exception {
		int sum = 0;
		for (int i = 0; i < 100; i++) {
			Thread.sleep(200);
			sum += i;
			System.out.println("Mythread3: "+i);
		}
		return String.valueOf(sum+300000);
	}
}
 
class MyThreadt44 implements Callable<String>{
	private String commandstr;          // 要运行的mingling
	public MyThreadt44(String commandstr) {
		this.commandstr = commandstr;
	}
	@Override
	public String call() throws Exception {
		int sum = 0;
		for (int i = 0; i < 50; i++) {
			Thread.sleep(200);
			sum += i;
			System.out.println("Mythread4: "+i);
		}
		return String.valueOf(sum+400000);
	}
}

CompletionService法)。get()メソッドは、completionService.takeにより、スレッド(リターンを完了するために、最速を取得する結果(実行が最速の実行スレッドの終了完了するまで、現在のスレッドがブロックされていない場合)、2回目の呼び出しは2番手のリターンがあります完全なスレッドは結果を返します。

3、CompletableFutureインタフェース

いわゆる非同期呼び出しは、実際に呼び出される関数の戻り値を待たずに達成し、操作の方法を実行し続けてみましょうさ。単純な話では通話が継続するか、結果を待たずに戻るには、計算の一部に呼び出しを完了するために別のスレッドを開始することです。しかし、呼び出し側は、まだスレッドの結果を取る必要があります。

将来インタフェースはJDK1.5加え、非同期計算を説明するために使用されます。将来と非同期メソッドの関連する使用は、タスクを実行する機能を提供しますが、結果を得るために非常に便利ですが、タスクは、ポーリングによって結果を取得したり、道を遮断することができます。

JDK1.8がCompletableFutureインタフェースと今後CompletionStage二つのインターフェースを提案した後、CompletionStageプロセスにおける特定の段階に代わって非同期タスクの実行(CompletionStage非同期計算の抽象プロセスとして見ることができ、それは段階の完了後に別のものを引き起こす可能性位相、位相計算を行う関数であってもよい、消費者またはRunnableをなど。

stage.thenApply。(X - >四角( x))をthenAccept(X - > System.out.print(x))をthenRun(() - >のSystem.out.println())。)
私たちは、タスクを作成することができますし、CompletableFutureに基づきますチェーンハンドル複数のタスクとタスクは、タスクを完了するために基づいて取得した結果を達成するために。

(1)タスクを作成します。

Runnableオブジェクト(ノーリターン値)を実行するために新しいスレッドを使用して## runAsync方法。

## supplyAysncサプライヤオブジェクト(戻り値)を実行するために新しいスレッドを使用する方法を。

##スレッドプールに基づいて作成

(2)非同期処理タスク

かかわらずFuture.get()メソッドまたはCompletableFuture.get()メソッドは現在のスレッドをブロックせずにタスクの実行の結果を得るために、我々は、組み合わせCompletionStageを使用することができ、ブロックされたタスクを処理するための非同期コールバックを提供します。

## whenCompleteは:whenCompleteタスクを続行するために、現在のタスクのスレッドの実行です。
## whenCompleteAsync:このタスクは並列に実行され、実行のためのスレッドプールに提出し続けることwhenCompleteAsync。

## thenApply:スレッドが別のスレッドに依存している場合、これらの方法は、thenApply 2つのスレッド・シリアライゼーションを使用することができます

## thenAccept本段の入力と消費プロセスとして受信thenAccept出力段には、結果を返しません。

## thenRun:それは入力パラメータ、消費者の取り扱いを必要としないため、前段階の結果を気にしない、結果は返されません。

## thenCombine:2つの意志のCompletionStageタスクが実行された後、thenCombineには2つのタスクの結果は、
に対処します。

## applyToEither:2 CompletionStage、結果の迅速な復帰を行って、私はCompletionStageその結果、次のステップ変換アクションになります。

## acceptEither方法:2 CompletionStage、結果の迅速な復帰を行って、私は結果と次のステップを消費することCompletionStageの操作

public class TestCompletableFuture {
	private static final String commandstr01 = "hahah";
	private static final String commandstr02 = "hahah";
	private static final String commandstr03 = "hahah";
	private static final String commandstr04 = "hahah";
 
	    public static void main(String[] args) throws InterruptedException, ExecutionException{
	        
	    	ExecutorService executorService = Executors.newCachedThreadPool();
	    	
	        CompletableFuture.supplyAsync(new MyThreadt444(commandstr02),executorService).whenComplete((result, e) -> {
	        	//执行线程执行完以后的操作。
	            System.out.println(result + " " + e);
	        }).exceptionally((e) -> {
	            //抛出异常
	        	System.out.println("exception " + e);
	            return "exception";
	        });
	        
	         CompletableFuture.supplyAsync(new MyThreadt333(commandstr02),executorService).whenComplete((result, e) -> {
	        	//执行线程执行完以后的操作。
	        	System.out.println(result + " " + e);
	        }).exceptionally((e) -> {
	            System.out.println("exception " + e);
	            return "exception";
	        });
	    }
}
 
 
 
class MyThreadt333 implements Supplier<String>{
 
	private String commandstr;          // 要运行的mingling
	public MyThreadt333(String commandstr) {
		this.commandstr = commandstr;
	}
	@Override
	public String get() {
		int sum = 0;
		for (int i = 0; i < 30; i++) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			sum += i;
			System.out.println("Mythread333: "+i);
		}
		return String.valueOf(sum+300000);
	}
}
 
class MyThreadt444 implements Supplier<String>{
 
	private String commandstr;          // 要运行的mingling
	public MyThreadt444(String commandstr) {
		this.commandstr = commandstr;
	}
	@Override
	public String get() {
		int sum = 0;
		for (int i = 0; i < 40; i++) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			sum += i;
			System.out.println("Mythread444: "+i);
		}
		return String.valueOf(sum+400000);
	}
}

インタフェースCompletableFuture whenCompleteハンドル等を使用することに加えて、タスクを完了するために、結果の取得に応じてタスクを達成するために使用されてもよいです。

図4に示すように、いくつかの方法の結果を要約取るマルチスレッド
ここに画像を挿入説明

公開された54元の記事 ウォン称賛28 ビュー4213

おすすめ

転載: blog.csdn.net/qq_37174887/article/details/103431362