A、CountDowmLatch(ラッチ)(ダウンカウンタラッチ)
下に位置たCountDownLatchクラスjava.util.concurrentパッケージは、特定の操作が完了すると、操作の唯一の他の全てのスレッドが終了し、現在の運転を継続しなければなりません。
同様のカウンタ機能を実現するために使用します。他に実行するために4つのタスクの完了後に実行するために例えば、タスクAがあり、それは、あなたがこの機能を実装するためにされたCountDownLatchを使用することができ、待機します。
1 ファイナル AたCountDownLatch LATCH = 新しい新たCountDownLatch(2 );
2 新しい新しいスレッド(){
3 公共 ボイドRUN(){
。4 。のSystem.out.println( "子スレッド" +にThread.currentThread()のgetName() + "が実行されています" )
。5 のThread.sleep(3000 )
。6 のSystem.out.println( "子スレッド" +にThread.currentThread()のgetName() + " 終了しました。" )
。7 latch.countDown();
8 };
9 } .start();
10 新しい新しいスレッド(){
11 公共 ボイドRUN(){
12であります System.out.println( "子スレッド" +にThread.currentThread()のgetName() + " 実行" );
13である のThread.sleep(3000 );
14 のSystem.out.println( "子スレッド" +にThread.currentThread ().getName()+ "完成" );
15 latch.countDown();
16 };
17 } .start();
18であるのSystem.out.println( "スレッドを待って完成サブ2 ...です" )。
。19 )(latch.await;
20であるのSystem.out.println( "スレッドが終了し、サブ2を有している" );
21であるのSystem.out.println( "続行するメインスレッド" );
22 }
二つ、セマフォ(セマフォ - 同時にアクセススレッドの数を制御)
セマフォは、同時にアクセスするスレッドの数を制御待機しない場合、)(取得してライセンスを取得しますが、ライセンスが解放によって解放されることができます()。
いくつかの方法で、より重要なセマフォクラス:
1)公共無効取得():ライセンスが取得できない場合は、ライセンスを取得するために使用されるが、それはその許可を知って、待機する必要があります。
2)公共無効取得(int型の許可):許可ライセンスを取得。
3)公共のボイドリリース(){}:無料ライセンス、注意、ライセンスをリリースする前に、ライセンスを取得する必要があります。
4)公共ボイド放出(INT許可){}:許可ライセンスを解放します。
上記の4つの方法は、あなたがすぐに結果を取得したい場合は、次のいくつかのメソッドを使用することができ、ブロックされます。
1)公共ブールtryAcquire():、ライセンスを取得しようとする買収が成功すれば、その後すぐに買収が失敗した場合、それはすぐにfalseを返し、trueを返します。
2)公共ブールtryAcquire(長いタイムアウト、TimeUnitで単位):ライセンスを取得しようとする試みは、指定された時間内に成功した場合、直ちにそれ以外の場合は、すぐに偽を返し、trueを返します。
3)公共ブールtryAcquire(int型の許可を):取得に失敗した場合に許可のライセンスを取得しようと、買収が成功すれば、その後すぐにtrueを返します、それはすぐにfalseを返します。
4)公共ブールtryAcquire(int型の許可、長いタイムアウト、TimeUnitで単位):指定された時間内に成功した場合、その後すぐにtrueを返し、許可のライセンスを取得しようとする試みは、それ以外の場合は、すぐにfalseを返します。
5)またavailablePermitsによって使用可能なライセンスの数を取得する()メソッドであってもよいです。
例:工場出荷時は、同時に5台のマシン、一台のマシンを持っているだけで、作業者が使用することができた場合は、単に他の労働者が継続して、走りました。その後、我々はセマフォによって行うことができます。
1 int N = 8; //工人数
2 Semaphore semaphore = new Semaphore(5); //机器数目
3 for(int i=0;i<N;i++){
4 new Worker(i,semaphore).start();
5 }
6 static class Worker extends Thread{
7 private int num;
8 private Semaphore semaphore;
9 public Worker(int num,Semaphore semaphore){
10 this.num = num;
11 this.semaphore = semaphore;
12 }
13 public void run() {
14 try {
15 semaphore.acquire();
16 System.out.println("工人"+this.num+"占用一个机器在生产...");
17 Thread.sleep(2000);
18 System.out.println("工人"+this.num+"释放出机器");
19 semaphore.release();
20 } catch (InterruptedException e) {
21 e.printStackTrace();
22 }
23 }
24 }
三、CyclicBarrier(回环栅栏-等待至barrier状态再全部同时执行)
回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行,叫做回环,是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这种状态叫做barrier,当调用await()方法之后,线程就处于barrier了。
CyclicBarrier中最重要的方法就是await方法,它有两个重载版本:
1)public int await():用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务。
2)public int await(long timeout,TimeUnit unit):让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。
具体使用如下:
1 public static void main(String[] args) {
2 int N = 4;
3 CyclicBarrier barrier = new CyclicBarrier(N);
4 for(int i=0;i<N;i++)
5 new Writer(barrier).start();
6 }
7 static class Writer extends Thread{
8 private CyclicBarrier cyclicBarrier;
9 public Writer(CyclicBarrier cyclicBarrier) {
10 this.cyclicBarrier = cyclicBarrier;
11 }
12 public void run() {
13 try {
14 Thread.sleep(5000); //以睡眠来模拟线程需要预定写入数据操作
15 System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
16 cyclicBarrier.await();
17 } catch (InterruptedException e) {
18 e.printStackTrace();
19 }catch(BrokenBarrierException e){
20 e.printStackTrace();
21 }
22 System.out.println("所有线程写入完毕,继续处理其他任务,比如数据操作");
23 }
24 }
三者之间的联系与区别:
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。CountDownLatch一般用于某个线程A等待若干个线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行。另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。
Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。