自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JUC - CountDownLach原理分析

開(kāi)發(fā) 后端
CountDownLatch 和 Semaphore 一樣都是共享模式下資源問(wèn)題,這些源碼實(shí)現(xiàn)AQS的模版方法,然后使用CAS+循環(huán)重試實(shí)現(xiàn)自己的功能。

[[345820]]

 CountDownLach閉鎖
背景

  • CountDownLatch是在Java1.5被引入,跟它一起被引入的工具類(lèi)還有CyclicBarrier、Semaphore、ConcurrenthashMap和BlockingQueue。
  • 在java.util.cucurrent包下。

概念

  • CountDownLatch這個(gè)類(lèi)使一個(gè)線程等待其它線程各自執(zhí)行完畢后再執(zhí)行。
  • 是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的,計(jì)數(shù)器的初始值是線程的數(shù)量。每當(dāng)一個(gè)線程執(zhí)行完畢后,計(jì)數(shù)器的值就-1,當(dāng)計(jì)數(shù)器的值為0時(shí),表示所有線程都執(zhí)行完畢,然后在閉鎖上等待的線程就可以恢復(fù)工作來(lái)。

源碼

  • countDownLatch類(lèi)中只提供了一個(gè)構(gòu)造器
  1. public CountDownLatch(int count) { 
  2.   if (count < 0) throw new IllegalArgumentException("count < 0"); 
  3.      this.sync = new Sync(count); 
  • 類(lèi)中有三個(gè)方法是最重要的
  1. // 調(diào)用await()方法的線程會(huì)被掛起,它會(huì)等待直到count值為0才繼續(xù)執(zhí)行 
  2. public void await() throws InterruptedException { 
  3.         sync.acquireSharedInterruptibly(1); 
  4.     }//和await()方法類(lèi)似,只不過(guò)等待一定的時(shí)間后count值還沒(méi)變?yōu)?的化就會(huì)繼續(xù)執(zhí)行 
  5. public boolean await(long timeout, TimeUnit unit) 
  6.         throws InterruptedException {        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); 
  7.     }//將count值減1 
  8. public void countDown() {        sync.releaseShared(1); 
  9.     } 

示例
普通示例:

  1. public class CountDownLatchTest { 
  2.     public static void main(String[] args) { 
  3.         final CountDownLatch latch = new CountDownLatch(2); 
  4.         System.out.println("主線程開(kāi)始執(zhí)行…… ……"); 
  5.         //第一個(gè)子線程執(zhí)行 
  6.         ExecutorService es1 = Executors.newSingleThreadExecutor(); 
  7.         es1.execute(new Runnable() { 
  8.             @Override 
  9.             public void run() { 
  10.                 try { 
  11.                     Thread.sleep(3000); 
  12.                     System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); 
  13.                 } catch (InterruptedException e) { 
  14.                     e.printStackTrace(); 
  15.                 } 
  16.                 latch.countDown(); 
  17.             } 
  18.         }); 
  19.         es1.shutdown(); 
  20.         //第二個(gè)子線程執(zhí)行 
  21.         ExecutorService es2 = Executors.newSingleThreadExecutor(); 
  22.         es2.execute(new Runnable() { 
  23.             @Override 
  24.             public void run() { 
  25.                 try { 
  26.                     Thread.sleep(3000); 
  27.                 } catch (InterruptedException e) { 
  28.                     e.printStackTrace(); 
  29.                 } 
  30.                 System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); 
  31.                 latch.countDown(); 
  32.             } 
  33.         }); 
  34.         es2.shutdown(); 
  35.         System.out.println("等待兩個(gè)線程執(zhí)行完畢…… ……"); 
  36.         try { 
  37.             latch.await(); 
  38.         } catch (InterruptedException e) { 
  39.             e.printStackTrace(); 
  40.         } 
  41.         System.out.println("兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程"); 
  42.     } 

結(jié)果集:

  1. 主線程開(kāi)始執(zhí)行…… …… 
  2. 等待兩個(gè)線程執(zhí)行完畢…… ……子線程:pool-1-thread-1執(zhí)行子線程:pool-2-thread-1執(zhí)行兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程 

模擬并發(fā)示例:

  1. public class Parallellimit { 
  2.     public static void main(String[] args) { 
  3.         ExecutorService pool = Executors.newCachedThreadPool();        CountDownLatch cdl = new CountDownLatch(100); 
  4.         for (int i = 0; i < 100; i++) { 
  5.             CountRunnable runnable = new CountRunnable(cdl); 
  6.             pool.execute(runnable);        }    }} class CountRunnable implements Runnable { 
  7.     private CountDownLatch countDownLatch; 
  8.     public CountRunnable(CountDownLatch countDownLatch) { 
  9.         this.countDownLatch = countDownLatch; 
  10.     }    @Override 
  11.     public void run() { 
  12.         try { 
  13.             synchronized (countDownLatch) {                /*** 每次減少一個(gè)容量*/ 
  14.                 countDownLatch.countDown();                System.out.println("thread counts = " + (countDownLatch.getCount())); 
  15.             }            countDownLatch.await(); 
  16.             System.out.println("concurrency counts = " + (100 - countDownLatch.getCount())); 
  17.         } catch (InterruptedException e) { 
  18.             e.printStackTrace();        }    }} 

源碼分析

  1. public class CountDownLatch { 
  2.     //繼承AQS來(lái)實(shí)現(xiàn)他的模板方法(tryAcquireShared,tryReleaseShared) 
  3.     private static final class Sync extends AbstractQueuedSynchronizer {       //計(jì)數(shù)個(gè)數(shù)Count 
  4.         Sync(int count) { 
  5.             setState(count);        }        int getCount() { 
  6.             return getState(); 
  7.         }      //AQS方法getState(),返回同步狀態(tài),這里指計(jì)數(shù)器值        protected int tryAcquireShared(int acquires) { 
  8.             return (getState() == 0) ? 1 : -1; 
  9.         }       //循環(huán)+cas重試 直到計(jì)數(shù)器為0 跳出,則release(實(shí)現(xiàn)aqs共享模式釋放方法) 
  10.         protected boolean tryReleaseShared(int releases) { 
  11.             // Decrement count; signal when transition to zero 
  12.             for (;;) { 
  13.                 int c = getState(); 
  14.                 if (c == 0) 
  15.                     return false
  16.                 int nextc = c-1; 
  17.                 if (compareAndSetState(c, nextc)) 
  18.                     return nextc == 0; 
  19.             }        }    }    private final Sync sync;   //實(shí)例化 
  20.     public CountDownLatch(int count) { 
  21.         if (count < 0) throw new IllegalArgumentException("count < 0"); 
  22.         this.sync = new Sync(count);    }    public void await() throws InterruptedException {        sync.acquireSharedInterruptibly(1); 
  23.     }  //帶有一個(gè)超時(shí)時(shí)間的awit    public boolean await(long timeout, TimeUnit unit)        throws InterruptedException {        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); 
  24.     }      public void countDown() {        sync.releaseShared(1); 
  25.     }    public long getCount() {        return sync.getCount(); 
  26.     }} 

總結(jié)
CountDownLatch 和 Semaphore 一樣都是共享模式下資源問(wèn)題,這些源碼實(shí)現(xiàn)AQS的模版方法,然后使用CAS+循環(huán)重試實(shí)現(xiàn)自己的功能。在RT多個(gè)資源調(diào)用,或者執(zhí)行某種操作依賴(lài)其他操作完成下可以發(fā)揮這個(gè)計(jì)數(shù)器的作用。

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2020-11-03 09:10:18

JUC-Future

2022-04-13 08:23:31

Golang并發(fā)

2021-10-12 17:19:17

Random局限性變量

2023-04-26 08:39:41

Bitmap元素存儲(chǔ)

2012-12-03 16:57:37

HDFS

2015-09-23 16:14:03

Ryu拓?fù)浣Y(jié)構(gòu)

2022-04-12 08:30:45

TomcatWeb 應(yīng)用Servlet

2023-02-07 09:17:19

Java注解原理

2009-11-06 09:22:46

WCF應(yīng)用

2021-11-26 17:17:43

Android廣播運(yùn)行原理源碼分析

2017-02-09 13:23:46

2015-06-15 10:12:36

Java原理分析

2021-04-21 15:17:10

WebsocketWsnodejs

2021-08-09 11:15:28

MybatisJavaSpring

2024-01-12 07:38:38

AQS原理JUC

2012-03-06 11:01:44

Java

2010-06-29 17:07:10

Linux SNMP代

2022-08-08 07:33:11

自動(dòng)裝配Java容器

2020-03-02 19:08:21

JVMJDKJRE

2009-03-26 13:43:59

實(shí)現(xiàn)Order ByMySQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)