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