java count 在哪一类里_java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用...
先來講解一下Semaphore信號燈的作用:
可以維護當前訪問自身的線程個數,并提供了同步機制,
使用semaphore可以控制同時訪問資源的線程個數
例如,實現一個文件允許的并發訪問數。
請看下面的演示代碼:
1 public classSemaphoreTest2 {3 public static voidmain(String[] args)4 {5 //創建一個帶有緩存的線程池
6 ExecutorService service =Executors.newCachedThreadPool();7 //創建三個信號燈
8 final Semaphore sp = new Semaphore(3);//最多并發三個線程 此處可以按照需求去修改9 //開啟十個線程
10 for (int i = 1; i <= 10; i++)11 {12 //只有三個線程可以同時進入 其余線程等待
13 service.execute(newRunnable()14 {15 @Override16 public voidrun()17 {18 try
19 {20 sp.acquire();//獲取一盞信號燈
21 } catch(InterruptedException e)22 {23 e.printStackTrace();24 }25 System.out.println("線程 "+Thread.currentThread().getName()+" 進入"
26 + " ,當前已有 "+(3-sp.availablePermits())+ " 個并發");27 try
28 {29 Thread.sleep(new Random().nextInt(1000));30 } catch(InterruptedException e)31 {32 e.printStackTrace();33 }34 System.out.println("線程 "+Thread.currentThread().getName()+" 即將離開 ");35 sp.release();//釋放
36 System.out.println("線程 "+Thread.currentThread().getName()+" 已經離開"
37 + " ,當前已有 "+(3-sp.availablePermits())+ " 個并發");38 }39 });40 }41 service.shutdown();42 }43 }
執行結果如下:
線程 pool-1-thread-2 進入 ,當前已有 2個并發
線程 pool-1-thread-3 進入 ,當前已有 3個并發
線程 pool-1-thread-1 進入 ,當前已有 3個并發
線程 pool-1-thread-3即將離開
線程 pool-1-thread-3 已經離開 ,當前已有 2個并發
線程 pool-1-thread-4 進入 ,當前已有 3個并發
線程 pool-1-thread-1即將離開
線程 pool-1-thread-5 進入 ,當前已有 3個并發
線程 pool-1-thread-1 已經離開 ,當前已有 3個并發
線程 pool-1-thread-2即將離開
線程 pool-1-thread-2 已經離開 ,當前已有 2個并發
線程 pool-1-thread-6 進入 ,當前已有 3個并發
線程 pool-1-thread-6即將離開
線程 pool-1-thread-6 已經離開 ,當前已有 2個并發
線程 pool-1-thread-7 進入 ,當前已有 3個并發
線程 pool-1-thread-7即將離開
線程 pool-1-thread-7 已經離開 ,當前已有 2個并發
線程 pool-1-thread-8 進入 ,當前已有 3個并發
線程 pool-1-thread-4即將離開
線程 pool-1-thread-4 已經離開 ,當前已有 2個并發
線程 pool-1-thread-9 進入 ,當前已有 3個并發
線程 pool-1-thread-5即將離開
線程 pool-1-thread-5 已經離開 ,當前已有 2個并發
線程 pool-1-thread-10 進入 ,當前已有 3個并發
線程 pool-1-thread-10即將離開
線程 pool-1-thread-10 已經離開 ,當前已有 2個并發
線程 pool-1-thread-8即將離開
線程 pool-1-thread-8 已經離開 ,當前已有 1個并發
線程 pool-1-thread-9即將離開
線程 pool-1-thread-9 已經離開 ,當前已有 0 個并發
View Code
Semaphore信號燈可以控制并發數,保證每次最多只能有三個線程在線程池中。
CyclicBarrier類的使用,可以模擬現實生活中的多人等待上車的情形,例如多人去旅行,那么當A到達集合點時,不能立即出發,必須等到B也到達集合點,那么A和B必須等到C也到達集合點,此時,三人可以坐車出發去下一站。該類就可以實現此功能,請看如下代碼。
1 public classCyclicBarrierTest2 {3 public static voidmain(String[] args)4 {5 //創建一個帶有緩存的線程池
6 ExecutorService service =Executors.newCachedThreadPool();7 //指定三個線程 只有當三個線程同時到達時 程序才會往下執行
8 final CyclicBarrier cb = new CyclicBarrier(3);9
10 for (int i = 0; i < 3; i++)11 {12 Runnable runnable = newRunnable()13 {14 @Override15 public voidrun()16 {17 try
18 {19 /**
20 * cb.getNumberWaiting():從0開始,獲取當前等待的線程數量21 */
22 //第一個
23 Thread.sleep(new Random().nextInt(1000));24 System.out.println("線程 "+Thread.currentThread().getName()+" 即將到達集合地點1,"
25 + "當前已有"+(cb.getNumberWaiting()+1)+" 個線程,"+(cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在繼續等待"));26 cb.await();//讓線程等待27
28 //第二個
29 Thread.sleep(new Random().nextInt(1000));30 System.out.println("線程 "+Thread.currentThread().getName()+" 即將到達集合地點2,"
31 + "當前已有"+(cb.getNumberWaiting()+1)+" 個線程,"+(cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在繼續等待"));32 cb.await();33
34 //第三個
35 Thread.sleep(new Random().nextInt(1000));36 System.out.println("線程 "+Thread.currentThread().getName()+" 即將到達集合地點3,"
37 + "當前已有"+(cb.getNumberWaiting()+1)+" 個線程,"+(cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在繼續等待"));38 cb.await();39 } catch (InterruptedException |BrokenBarrierException e)40 {41 e.printStackTrace();42 }43 }44 };45 service.execute(runnable);46 }47
48 service.shutdown();//關閉線程池
49 }50 }
如下是執行結果:
1 線程 pool-1-thread-2即將到達集合地點1,當前已有1 個線程,正在繼續等待2 線程 pool-1-thread-1即將到達集合地點1,當前已有2 個線程,正在繼續等待3 線程 pool-1-thread-3即將到達集合地點1,當前已有3 個線程,都到齊了,繼續走啊4 線程 pool-1-thread-2即將到達集合地點2,當前已有1 個線程,正在繼續等待5 線程 pool-1-thread-1即將到達集合地點2,當前已有2 個線程,正在繼續等待6 線程 pool-1-thread-3即將到達集合地點2,當前已有3 個線程,都到齊了,繼續走啊7 線程 pool-1-thread-1即將到達集合地點3,當前已有1 個線程,正在繼續等待8 線程 pool-1-thread-2即將到達集合地點3,當前已有2 個線程,正在繼續等待9 線程 pool-1-thread-3 即將到達集合地點3,當前已有3 個線程,都到齊了,繼續走啊
View Code
CountDownLatch計數器的使用:
* 演示一個計數器CountDownLatch
* 模擬百米賽跑
* 1個裁判 吹口哨
* 3個運動員
1 public classCountDownLatchTest2 {3 public static voidmain(String[] args)4 {5 //創建一個帶有緩存的線程池
6 ExecutorService service =Executors.newCachedThreadPool();7 final CountDownLatch cdOrder = new CountDownLatch(1);//裁判
8 final CountDownLatch cdAnswer = new CountDownLatch(3);//運動員
9 for (int i = 0; i < 3; i++)10 {11 Runnable runnable = newRunnable()12 {13 @Override14 public voidrun()15 {16 try
17 {18 System.out.println("線程"+Thread.currentThread().getName()+" 正準備接收命令 ");19 cdOrder.await();//等待計數器歸0時 代碼向下走
20 System.out.println("線程"+Thread.currentThread().getName()+" 已接收命令 ");21 Thread.sleep(new Random().nextInt(1000));22 System.out.println("線程"+Thread.currentThread().getName()+" 回應命令處理結果 ");23 cdAnswer.countDown();//沒調用一次該方法 就會將當前計數器上的計數減1
24 } catch(InterruptedException e)25 {26 e.printStackTrace();27 }28 }29 };30 service.execute(runnable);31 }32
33
34 //主線恒
35 try
36 {37 Thread.sleep(new Random().nextInt(1000));38 System.out.println("線程"+Thread.currentThread().getName()+" 即將發布命令 ");39 cdOrder.countDown();//相當于把計數器身上的計數減1
40 System.out.println("線程"+Thread.currentThread().getName()+" 已發送命令,正在等待結果 ");41 cdAnswer.await();42 System.out.println("線程"+Thread.currentThread().getName()+" 已收到所有相應結果");43 } catch(InterruptedException e)44 {45 e.printStackTrace();46 }47 service.shutdown();//關閉線程池
48 }49 }
如下是執行結果:
1 線程pool-1-thread-1正準備接收命令2 線程pool-1-thread-2正準備接收命令3 線程pool-1-thread-3正準備接收命令4 線程main 即將發布命令5 線程main 已發送命令,正在等待結果6 線程pool-1-thread-1已接收命令7 線程pool-1-thread-2已接收命令8 線程pool-1-thread-3已接收命令9 線程pool-1-thread-2回應命令處理結果10 線程pool-1-thread-3回應命令處理結果11 線程pool-1-thread-1回應命令處理結果12 線程main 已收到所有相應結果
View Code
Exchanger類可以實現兩個線程之間的數據交換:
1 public classExchangerTest2 {3 public static voidmain(String[] args)4 {5 //創建一個帶有緩存的線程池
6 ExecutorService service =Executors.newCachedThreadPool();7 final Exchanger changer = new Exchanger();8 //開啟第一個任務
9 service.execute(newRunnable()10 {11 @Override12 public voidrun()13 {14 try
15 {16 String dtail1 = "zhangsan";//準備要交換出去的數據
17 System.out.println("線程 "+Thread.currentThread().getName()+" 正要把"+dtail1+"換出去");18 Thread.sleep(new Random().nextInt(1000));19 String dtail2 = changer.exchange(dtail1);//換回來的數據
20 System.out.println("線程 "+Thread.currentThread().getName()+"換回的數據為"+dtail2);21 } catch(InterruptedException e)22 {23 e.printStackTrace();24 }25 }26 });27
28 //開啟第二個任務
29 service.execute(newRunnable()30 {31 @Override32 public voidrun()33 {34 try
35 {36 String dtail1 = "lisi";//準備要交換出去的數據
37 System.out.println("線程 "+Thread.currentThread().getName()+" 正要把"+dtail1+"換出去");38 Thread.sleep(new Random().nextInt(1000));39 String dtail2 = changer.exchange(dtail1);//換回來的數據
40 System.out.println("線程 "+Thread.currentThread().getName()+"換回的數據為"+dtail2);41 } catch(InterruptedException e)42 {43 e.printStackTrace();44 }45 }46 });47 service.shutdown();48 }49 }
如下是執行結果:
1 線程 pool-1-thread-1正要把zhangsan換出去2 線程 pool-1-thread-2正要把lisi換出去3 線程 pool-1-thread-1換回的數據為lisi4 線程 pool-1-thread-2換回的數據為zhangsan
View Code
以上都是java 5中的一些知識點,大家可以根據實際工作中的需要進行選擇使用!!
總結
以上是生活随笔為你收集整理的java count 在哪一类里_java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java创新型模式_java设计模式--
- 下一篇: 天津民航大学是211还是985(中国民航