JavaでCyclicBarrierサイクルバリアを適用する方法
1. はじめに
CyclicBarrier は文字通りループ バリア (循環バリア) を意味し、スレッドのグループを特定の状態 (バリア ポイント) で待機させ、すべてを同時に実行できます。これは、待機中のスレッドがすべて解放された後に CyclicBarrier を再利用できるため、ループバックと呼ばれます。
CyclicBarrier の機能は、スレッドのグループを相互に待機させることです。共通点に達すると、それまで待機していたすべてのスレッドが実行を継続し、CyclicBarrier関数は再利用できます。
#2. CyclicBarrier の使用
構築方法:
// parties表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 public CyclicBarrier(int parties) // 用于在线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景(该线程的执行时机是在到达屏障之后再执行)
重要な方法:
//屏障 指定数量的线程全部调用await()方法时,这些线程不再阻塞 // BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时 public int await() throws InterruptedException, BrokenBarrierException public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException //循环 通过reset()方法可以进行重置
- CyclicBarrier の使用は、マルチスレッド データが計算され、計算結果が最終的にマージされるシナリオで使用できます。 #CyclicBarrier のカウンターリセットとバリア再利用の特徴を利用し、「完全出発」に近いシナリオにも対応可能です。 ##シミュレーション マージ計算シナリオ
CyclicBarrier を使用すると、複数のスレッドでデータを計算し、最終的に計算結果をマージすることができます。
public class CyclicBarrierTest2 { //保存每个学生的平均成绩 private Conc urrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>(); private ExecutorService threadPool= Executors.newFixedThreadPool(3); private CyclicBarrier cb=new CyclicBarrier(3,()->{ int result=0; Set<String> set = map.keySet(); for(String s:set){ result+=map.get(s); } System.out.println("三人平均成绩为:"+(result/3)+"分"); }); public void count(){ for(int i=0;i<3;i++){ threadPool.execute(new Runnable(){ @Override public void run() { //获取学生平均成绩 int score=(int)(Math.random()*40+60); map.put(Thread.currentThread().getName(), score); System.out.println(Thread.currentThread().getName() +"同学的平均成绩为:"+score); try { //执行完运行await(),等待所有学生平均成绩都计算完毕 cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }); } } public static void main(String[] args) { CyclicBarrierTest2 cb=new CyclicBarrierTest2(); cb.count(); } }
ログイン後にコピー「バスが満員」のシーンをシミュレート
CyclicBarrierのカウンターのリセットとバリアの再利用ができる特性を利用し、「バスが満員」のようなシーンに対応できます。人がいっぱいです"
public class CyclicBarrierTest3 { public static void main(String[] args) { AtomicInteger counter = new AtomicInteger(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 5, 5, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), (r) -> new Thread(r, counter.addAndGet(1) + " 号 "), new ThreadPoolExecutor.AbortPolicy()); CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> System.out.println("裁判:比赛开始~~")); for (int i = 0; i < 10; i++) { threadPoolExecutor.submit(new Runner(cyclicBarrier)); } } static class Runner extends Thread{ private CyclicBarrier cyclicBarrier; public Runner (CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } @Override public void run() { try { int sleepMills = ThreadLocalRandom.current().nextInt(1000); Thread.sleep(sleepMills); System.out.println(Thread.currentThread().getName() + " 选手已就位, 准备共用时: " + sleepMills + "ms" + cyclicBarrier.getNumberWaiting()); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); }catch(BrokenBarrierException e){ e.printStackTrace(); } } } }
プレーヤー No. 1配置され、共有する準備ができています: 395ms1## プレーヤー No. 5 が配置され、共有する準備ができています: 733ms2 プレーヤー No. 2 が配置され、共有する準備ができています: 776ms プレーヤー No. 3 が配置され、共有する準備ができています共有: 807ms4 主審: ゲームが開始されました ~~
4 人のプレーヤーが配置され、共有する準備ができました: 131ms03 人のプレーヤーが配置され、共有する準備ができました: 256ms12 人のプレーヤーが配置されます、共有準備完了: 291ms2
プレイヤー No. 1 が配置され、共有準備完了: 588ms3
プレイヤー No. 5 が配置され、共有準備完了: 763ms4
主審: ゲーム開始~~
3. CyclicBarrier のソース コード分析
CyclicBarrier プロセス
#メイン プロセスは次のとおりです:
ロックを取得し、カウント != 0 の場合はブロッキングに入ります;
ブロッキングに入る前に、まず条件キューに入り、次にロックを解放し、最後にブロックする必要があります;
カウント != 0 の場合、ウェイクアップが実行されます。条件キュー内のすべてのノードがブロッキング キューに変換されます。
- ## ウェイクアップ後、ロックが取得されます。ロックの取得が失敗した場合は、ロック ブロック キューに入ります。
- ロックの取得が成功した場合、ロックは解放され、スレッドは同期状態になります。キューが目覚めます。
以下は簡単なフローチャートです:
#よくある質問がいくつかありますか?
1. スレッドのグループは、バリアをトリガーする前に互いに待機します。最後のスレッドがバリアに到達した後、ウェイクアップ ロジックはどのように実装されますか。ウェイクアップ プロセスは次のとおりです。呼び出し
java.util.concurrent.locks.Condition#signalAll条件キュー上のすべてのノードを起動します。
3. 条件キューから同期キューへの変換の実装ロジック? 変換プロセス中、まず条件キュー内のブロックされているすべてのスレッドが起動され、次にロックが取得されます。取得に失敗した場合は、同期キューに入ります。
- CyclicBarrier と CountDownLatch の違い
- CountDownLatch のカウンターは 1 回しか使用できませんが、CyclicBarrier のカウンターはリセット()メソッド。したがって、CyclicBarrier は、より複雑なビジネス シナリオを処理できます。たとえば、計算エラーが発生した場合、カウンターをリセットしてスレッドを再実行できます。
- CountDownLatch はメイン スレッドをブロックしますが、CyclicBarrier はメイン スレッドをブロックせず、子スレッドのみをブロックします。
- CountDownLatch と CyclicBarrier はどちらもスレッド間の待機を実現できますが、焦点が異なります。 CountDownLatch は通常、1 つ以上のスレッドが他のスレッドがタスクを実行する前に完了するのを待つために使用されます。 CyclicBarrier は通常、スレッドのグループが互いに特定の状態に達するのを待機し、スレッドのグループが同時に実行されるようにするために使用されます。
- CyclicBarrier は、マルチスレッドの計算結果をマージするバリアアクションも提供できます。
- #CyclicBarrier は、ReentrantLock の「排他ロック」と Conditon を介してスレッドのグループのブロックとウェイクアップを実装します。一方、CountDownLatch は、AQS の「共有ロック」を介して実装されます。
以上がJavaでCyclicBarrierサイクルバリアを適用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4
