這篇文章主要為大家展示了java中CountDownLatch和CyclicBarrier有什么區(qū)別,內(nèi)容簡(jiǎn)而易懂,希望大家可以學(xué)習(xí)一下,學(xué)習(xí)完之后肯定會(huì)有收獲的,下面讓小編帶大家一起來看看吧。

為昌黎等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及昌黎網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站制作、做網(wǎng)站、昌黎網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
前言
CountDownLatch和CyclicBarrier兩個(gè)同為java并發(fā)編程的重要工具類,它們?cè)谥T多多線程并發(fā)或并行場(chǎng)景中得到了廣泛的應(yīng)用。但兩者就其內(nèi)部實(shí)現(xiàn)和使用場(chǎng)景而言是各有所側(cè)重的。
內(nèi)部實(shí)現(xiàn)差異
前者更多依賴經(jīng)典的AQS機(jī)制和CAS機(jī)制來控制器內(nèi)部狀態(tài)的更迭和計(jì)數(shù)器本身的變化,而后者更多依靠可重入Lock等機(jī)制來控制其內(nèi)部并發(fā)安全性和一致性。
public class {
//Synchronization control For CountDownLatch.
//Uses AQS state to represent count.
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
private final Sync sync;
... ...//
} public class CyclicBarrier {
/**
* Each use of the barrier is represented as a generation instance.
* The generation changes whenever the barrier is tripped, or
* is reset. There can be many generations associated with threads
* using the barrier - due to the non-deterministic way the lock
* may be allocated to waiting threads - but only one of these
* can be active at a time (the one to which {@code count} applies)
* and all the rest are either broken or tripped.
* There need not be an active generation if there has been a break
* but no subsequent reset.
*/
private static class Generation {
boolean broken = false;
}
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
/** The number of parties */
private final int parties;
/* The command to run when tripped */
private final Runnable barrierCommand;
/** The current generation */
private Generation generation = new Generation();
/**
* Number of parties still waiting. Counts down from parties to 0
* on each generation. It is reset to parties on each new
* generation or when broken.
*/
private int count;
/**
* Updates state on barrier trip and wakes up everyone.
* Called only while holding lock.
*/
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
}
/**
* Sets current barrier generation as broken and wakes up everyone.
* Called only while holding lock.
*/
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
/**
* Main barrier code, covering the various policies.
*/
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
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();
}
}
... ... //
}實(shí)戰(zhàn) - 展示各自的使用場(chǎng)景
/**
*類說明:共5個(gè)初始化子線程,6個(gè)閉鎖扣除點(diǎn),扣除完畢后,主線程和業(yè)務(wù)線程才能繼續(xù)執(zhí)行
*/
public class UseCountDownLatch {
static CountDownLatch latch = new CountDownLatch(6);
/*初始化線程*/
private static class InitThread implements Runnable{
public void run() {
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work......");
latch.countDown();
for(int i =0;i<2;i++) {
System.out.println("Thread_"+Thread.currentThread().getId()
+" ........continue do its work");
}
}
}
/*業(yè)務(wù)線程等待latch的計(jì)數(shù)器為0完成*/
private static class BusiThread implements Runnable{
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i =0;i<3;i++) {
System.out.println("BusiThread_"+Thread.currentThread().getId()
+" do business-----");
}
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
SleepTools.ms(1);
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work step 1st......");
latch.countDown();
System.out.println("begin step 2nd.......");
SleepTools.ms(1);
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work step 2nd......");
latch.countDown();
}
}).start();
new Thread(new BusiThread()).start();
for(int i=0;i<=3;i++){
Thread thread = new Thread(new InitThread());
thread.start();
}
latch.await();
System.out.println("Main do ites work........");
}
}/**
*類說明:共4個(gè)子線程,他們?nèi)客瓿晒ぷ骱螅怀鲎约航Y(jié)果,
*再被統(tǒng)一釋放去做自己的事情,而交出的結(jié)果被另外的線程拿來拼接字符串
*/
class UseCyclicBarrier {
private static CyclicBarrier barrier
= new CyclicBarrier(4,new CollectThread());
//存放子線程工作結(jié)果的容器
private static ConcurrentHashMap<String,Long> resultMap
= new ConcurrentHashMap<String,Long>();
public static void main(String[] args) {
for(int i=0;i<4;i++){
Thread thread = new Thread(new SubThread());
thread.start();
}
}
/*匯總的任務(wù)*/
private static class CollectThread implements Runnable{
@Override
public void run() {
StringBuilder result = new StringBuilder();
for(Map.Entry<String,Long> workResult:resultMap.entrySet()){
result.append("["+workResult.getValue()+"]");
}
System.out.println(" the result = "+ result);
System.out.println("do other business........");
}
}
/*相互等待的子線程*/
private static class SubThread implements Runnable{
@Override
public void run() {
long id = Thread.currentThread().getId();
resultMap.put(Thread.currentThread().getId()+"",id);
try {
Thread.sleep(1000+id);
System.out.println("Thread_"+id+" ....do something ");
barrier.await();
Thread.sleep(1000+id);
System.out.println("Thread_"+id+" ....do its business ");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}兩者總結(jié)
1. Cyclicbarrier結(jié)果匯總的Runable線程可以重復(fù)被執(zhí)行,通過多次觸發(fā)await()方法,countdownlatch可以調(diào)用await()方法多次;cyclicbarrier若沒有結(jié)果匯總,則調(diào)用一次await()就夠了;
2. New cyclicbarrier(threadCount)的線程數(shù)必須與實(shí)際的用戶線程數(shù)一致;
3. 協(xié)調(diào)線程同時(shí)運(yùn)行:countDownLatch協(xié)調(diào)工作線程執(zhí)行,是由外面線程協(xié)調(diào);cyclicbarrier是由工作線程之間相互協(xié)調(diào)運(yùn)行;
4. 從構(gòu)造函數(shù)上看出:countDownlatch控制運(yùn)行的計(jì)數(shù)器數(shù)量和線程數(shù)沒有關(guān)系;cyclicbarrier構(gòu)造中傳入的線程數(shù)等于實(shí)際執(zhí)行線程數(shù);
5. countDownLatch在不能基于執(zhí)行子線程的運(yùn)行結(jié)果做處理,而cyclicbarrier可以;
6. 就使用場(chǎng)景而言,countdownlatch 更適用于框架加載前的一系列初始化工作等場(chǎng)景; cyclicbarrier更適用于需要多個(gè)用戶線程執(zhí)行后,將運(yùn)行結(jié)果匯總再計(jì)算等典型場(chǎng)景;
以上就是關(guān)于java中CountDownLatch和CyclicBarrier有什么區(qū)別的內(nèi)容,如果你們有學(xué)習(xí)到知識(shí)或者技能,可以把它分享出去讓更多的人看到。
新聞名稱:java中CountDownLatch和CyclicBarrier有什么區(qū)別
轉(zhuǎn)載來于:http://www.chinadenli.net/article10/iphjgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、營(yíng)銷型網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)