激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解Java回環(huán)屏障CyclicBarrier

詳解Java回環(huán)屏障CyclicBarrier

2020-09-12 15:05java小新人 Java教程

這篇文章主要介紹了Java回環(huán)屏障CyclicBarrier的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下

  上一篇說的CountDownLatch是一個(gè)計(jì)數(shù)器,類似線程的join方法,但是有一個(gè)缺陷,就是當(dāng)計(jì)數(shù)器的值到達(dá)0之后,再調(diào)用CountDownLatch的await和countDown方法就會(huì)立刻返回,就沒有作用了,那么反正是一個(gè)計(jì)數(shù)器,為什么不能重復(fù)使用呢?于是就出現(xiàn)了這篇說的CyclicBarrier,它的狀態(tài)可以被重用;

一.簡(jiǎn)單例子

  用法其實(shí)和CountDownLatch差不多,也就是一個(gè)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器的值變?yōu)?之后,就會(huì)把阻塞的線程喚醒:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.demo.study;
 
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Study0216 {
 // 注意這里的構(gòu)造器,第一個(gè)參數(shù)表示計(jì)數(shù)器初始值
 // 第二個(gè)參數(shù)表示當(dāng)計(jì)數(shù)器的值變?yōu)?的時(shí)候就觸發(fā)的任務(wù)
 static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> {
  System.out.println("cyclicBarrier task ");
 });
 
 public static void main(String[] args) {
  // 新建兩個(gè)線程的線程池
  ExecutorService pool = Executors.newFixedThreadPool(2);
  // 線程1放入線程池中
  pool.submit(() -> {
   try {
    System.out.println("Thread1----await-begin");
    cyclicBarrier.await();
    System.out.println("Thread1----await-end");
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  // 線程2放到線程池中
  pool.submit(() -> {
   try {
    System.out.println("Thread2----await-begin");
    cyclicBarrier.await();
    System.out.println("Thread2----await-end");
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  // 關(guān)閉線程池,此時(shí)還在執(zhí)行的任務(wù)會(huì)繼續(xù)執(zhí)行
  pool.shutdown();
 }
}

詳解Java回環(huán)屏障CyclicBarrier

 我們?cè)倏纯碈yclicBarrier的復(fù)用性,這里比如有一個(gè)任務(wù),有三部分組成,分別是A,B,C,然后創(chuàng)建兩個(gè)線程去執(zhí)行這個(gè)任務(wù),必須要等到兩個(gè)線程都執(zhí)行完成A部分,然后才能開始執(zhí)行B,只有兩個(gè)線程都執(zhí)行完成B部分,才能執(zhí)行C:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.example.demo.study;
 
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Study0216 {
 // 這里的構(gòu)造器,只有一個(gè)參數(shù),表示計(jì)數(shù)器初始值
 static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
 
 public static void main(String[] args) {
  // 新建兩個(gè)線程的線程池
  ExecutorService pool = Executors.newFixedThreadPool(2);
  // 線程1放入線程池中
  pool.submit(() -> {
   try {
    System.out.println("Thread1----stepA-start");
    cyclicBarrier.await();
    
    System.out.println("Thread1----stepB-start");
    cyclicBarrier.await();
    
    System.out.println("Thread1----stepC-start");
    
    
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  // 線程2放到線程池中
  pool.submit(() -> {
   try {
    System.out.println("Thread2----stepA-start");
    cyclicBarrier.await();
    
    System.out.println("Thread2----stepB-start");
    cyclicBarrier.await();
    
    System.out.println("Thread2----stepC-start");
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  // 關(guān)閉線程池,此時(shí)還在執(zhí)行的任務(wù)會(huì)繼續(xù)執(zhí)行
  pool.shutdown();
 }
}

詳解Java回環(huán)屏障CyclicBarrier

二.基本原理

  我們看看一些重要屬性:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class CyclicBarrier {
 //這個(gè)內(nèi)部類只有一個(gè)boolean值
 private static class Generation {
  boolean broken = false;
 }
 
 //獨(dú)占鎖
 private final ReentrantLock lock = new ReentrantLock();
  //條件變量
 private final Condition trip = lock.newCondition();
  //保存線程的總數(shù)
 private final int parties;
 //這是一個(gè)任務(wù),通過構(gòu)造器傳遞一個(gè)任務(wù),當(dāng)計(jì)數(shù)器變?yōu)?之后,就可以執(zhí)行這個(gè)任務(wù)
 private final Runnable barrierCommand;
 //這類內(nèi)部之后一個(gè)boolean的值,表示屏障是否被打破
 private Generation generation = new Generation();
 //計(jì)數(shù)器
 private int count;
}

  構(gòu)造器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
//我們的構(gòu)造器初始值設(shè)置的是parties
public CyclicBarrier(int parties) {
 this(parties, null);
}
//注意,這里開始的時(shí)候是count等于parties
//為什么要有兩個(gè)變量呢?我們每次調(diào)用await方法的時(shí)候count減一,當(dāng)count的值變?yōu)?之后,怎么又還原成初始值呢?
//直接就把parties的值賦值給count就行了呀,簡(jiǎn)單吧!
public CyclicBarrier(int parties, Runnable barrierAction) {
 if (parties <= 0) throw new IllegalArgumentException();
 this.parties = parties;
 this.count = parties;
 this.barrierCommand = barrierAction;
}

  然后再看看await方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public int await() throws InterruptedException, BrokenBarrierException {
 try {
  //調(diào)用的是dowait方法
  return dowait(false, 0L);
 } catch (TimeoutException toe) {
  throw new Error(toe); // cannot happen
 }
}
 
//假設(shè)count等于3,有三個(gè)線程都在調(diào)用這個(gè)方法,默認(rèn)超時(shí)時(shí)間為0,那么首每次都只有一個(gè)線程可以獲取鎖,將count減一,不為0
//就會(huì)到下面的for循環(huán)中扔到條件隊(duì)列中掛起;直到第三個(gè)線程調(diào)用這個(gè)dowait方法,count減一等于0,那么當(dāng)前線程執(zhí)行任務(wù)之后,
//就會(huì)喚醒條件變量中阻塞的線程,并重置count為初始值3
private int dowait(boolean timed, long nanos)throws InterruptedException, BrokenBarrierException, TimeoutException {
 //獲取鎖
 final ReentrantLock lock = this.lock;
 lock.lock();
 try {
  //g中只有一個(gè)boolean值
  final Generation g = generation;
  //如果g中的值為true的時(shí)候,拋錯(cuò)
  if (g.broken)
   throw new BrokenBarrierException();
  //如果當(dāng)前線程中斷,就拋錯(cuò)
  if (Thread.interrupted()) {
   breakBarrier();
   throw new InterruptedException();
  }
  //count減一,再賦值給index
  int index = --count;
  //如果index等于0的時(shí)候,說明所有的線程已經(jīng)到屏障點(diǎn)了,就可以
  if (index == 0) { // tripped
   boolean ranAction = false;
   try {
    //執(zhí)行當(dāng)前線程的任務(wù)
    final Runnable command = barrierCommand;
    if (command != null)
     command.run();
    ranAction = true;
    //喚醒其他因?yàn)檎{(diào)用了await方法阻塞的線程
    nextGeneration();
    return 0;
   } finally {
    if (!ranAction)
     breakBarrier();
   }
  }
  //能到這里來,說明是count不等于0,也就是還有的線程沒有到屏障點(diǎn)
  for (;;) {
   try {
    //wait方法有兩種情況,一種是設(shè)置超時(shí)時(shí)間,一種是不設(shè)置超時(shí)時(shí)間
    //這里就是對(duì)超時(shí)時(shí)間進(jìn)行的一個(gè)判斷,如果設(shè)置的超時(shí)時(shí)間為0,則會(huì)在條件隊(duì)列中無限的等待下去,直到被喚醒
    //設(shè)置了超時(shí)時(shí)間,那就等待該時(shí)間
    if (!timed)
     trip.await();
    else if (nanos > 0L)
     nanos = trip.awaitNanos(nanos);
   } catch (InterruptedException ie) {
    if (g == generation && ! g.broken) {
     breakBarrier();
     throw ie;
    } else {
     Thread.currentThread().interrupt();
    }
   }
 
   if (g.broken)
    throw new BrokenBarrierException();
 
   if (g != generation)
    return index;
 
   if (timed && nanos <= 0L) {
    breakBarrier();
    throw new TimeoutException();
   }
  }
 } finally {
  //釋放鎖
  lock.unlock();
 }
}
 
//喚醒其他因?yàn)檎{(diào)用了await方法阻塞的線程
private void nextGeneration() {
 //喚醒條件變量中所有線程
 trip.signalAll();
 //重置count的值
 count = parties;
 generation = new Generation();
}
 
private void breakBarrier() {
 generation.broken = true;
 //重置count為初始值parties
 count = parties;
 //喚醒條件隊(duì)列中的所有線程
 trip.signalAll();
}

以上就是詳解Java回環(huán)屏障CyclicBarrier的詳細(xì)內(nèi)容,更多關(guān)于Java CyclicBarrier的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://www.cnblogs.com/wyq1995/p/12317630.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 久久久久久久久久久久99 | av电影免费在线看 | 久久国产精品电影 | 久久久久久久不卡 | 国产青草网| 成人在线视频精品 | 久草在线视频免费播放 | 一区播放 | 九草网 | 成人精品 | 久久日本 | 欧美一级黄 | 福利免费观看 | 欧美人与物videos另类 | av在线1| av在线日韩 | 欧洲成人一区 | 亚洲电影在线播放 | 亚洲精中文字幕二区三区 | 亚洲最大的成人网 | 91久久夜色精品国产网站 | 久久精品毛片 | 羞羞的视频免费在线观看 | 韩国一级免费视频 | 欧美日韩视频在线播放 | 国产18成人免费视频 | 精品成人av一区二区在线播放 | 午夜视频中文字幕 | chinesexxxx刘婷hd 黄色片网站在线免费观看 国产免费高清在线 | 国产亚洲精品综合一区91555 | 99最新地址 | 色婷婷久久久亚洲一区二区三区 | 四季久久免费一区二区三区四区 | 少妇一级淫片高潮流水电影 | 激情网站在线观看 | 羞羞视频一区二区 | 亚洲综合视频一区 | 毛片一级免费看 | 91精品国产综合久久久动漫日韩 | 亚洲精品成人久久久 | 91看片免费版 |