Countdownlatch , CyclicBarrier , Semaphore類

1.**

countdownlatch

**
多數用於任務拆分
2.

public class CountDownLatchExample {
 	 public static void main(String[] args) throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(20);
    Service service = new Service(latch);
    Runnable task = () -> service.exec();
   	for (int i = 0; i < 20; i++) {
      Thread thread = new Thread(task);
      thread.start();
	}
	    System.out.println("主線程等待. ");
	    latch.await();
	    System.out.println("主線程完成等待. ");
	}
}
  public class Service {
	  private CountDownLatch latch;
	  public Service(CountDownLatch latch) {
	    this.latch = latch;
	  }
  public void exec() {
    try {
      System.out.println(Thread.currentThread().getName() + " execute task. ");
      sleep(2);
      System.out.println(Thread.currentThread().getName() + " finished task. ");
    } finally {
      latch.countDown();
    }
  }
  private void sleep(int seconds) {
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

3.輸出

> Thread-0 execute task. 
Thread-1 execute task. 
Thread-2 execute task. 
Thread-3 execute task. 
Thread-4 execute task. 
主線程等待. 
Thread-0 finished task. 
Thread-4 finished task. 
Thread-3 finished task. 
Thread-1 finished task. 
Thread-2 finished task. 
主線程完成等待.

4.適合任務拆分,比如 一個老闆視察工作, 三個工人幹活,三個工作都完成工作之後,老闆再來視察
5.這樣使用countdownlatch比較合適
6.提高了任務效率, 多個線程併發執行不同任務,主線程等待所有任務都執行完 纔會執行

總結 : await()阻塞主線程, 做減法 , 計數器減爲0的時候,主線程纔會走 在最後等,

**

CyclicBarrier

**
總結 : await()阻塞 做加法,加到一定程度, 那麼主程序纔會走 在線程中間等,有一個線程在等待執行最後的東西

 public class Test  {
	    ExecutorService fi = Executors.newFixedThreadPool(5);
	    public static void main(String[] args) throws InterruptedException {
	       final CyclicBarrier barrier  = new CyclicBarrier(50, new Runnable() {
	            @Override
	            public void run() {
	                System.out.println("集齊東西執行最後任務");
	            }
	        });
	        for(int i = 0 ; i< 50;i++){
	            final int r = i;
	            new Thread(new Runnable() {
	                @Override
	                public void run() {
	                    System.out.println(r+"開始集齊東西"+Thread.currentThread().getName());
	                    try {
	                        barrier.await();
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    } catch (BrokenBarrierException e) {
	                        e.printStackTrace();
	                    }
	                }
	            }).start();
	        }
	        System.out.println("開始集齊東西"+Thread.currentThread().getName());
	    }
}

輸出

0開始集齊東西Thread-0
1開始集齊東西Thread-1
2開始集齊東西Thread-2
3開始集齊東西Thread-3
4開始集齊東西Thread-4
5開始集齊東西Thread-5
6開始集齊東西Thread-6
7開始集齊東西Thread-7
8開始集齊東西Thread-8
9開始集齊東西Thread-9
10開始集齊東西Thread-10
11開始集齊東西Thread-11
12開始集齊東西Thread-12
13開始集齊東西Thread-13
14開始集齊東西Thread-14
15開始集齊東西Thread-15
16開始集齊東西Thread-16
17開始集齊東西Thread-17
18開始集齊東西Thread-18
19開始集齊東西Thread-19
20開始集齊東西Thread-20
21開始集齊東西Thread-21
22開始集齊東西Thread-22
23開始集齊東西Thread-23
24開始集齊東西Thread-24
25開始集齊東西Thread-25
26開始集齊東西Thread-26
27開始集齊東西Thread-27
28開始集齊東西Thread-28
29開始集齊東西Thread-29
30開始集齊東西Thread-30
31開始集齊東西Thread-31
32開始集齊東西Thread-32
33開始集齊東西Thread-33
34開始集齊東西Thread-34
35開始集齊東西Thread-35
36開始集齊東西Thread-36
37開始集齊東西Thread-37
38開始集齊東西Thread-38
39開始集齊東西Thread-39
49開始集齊東西Thread-49
40開始集齊東西Thread-40
48開始集齊東西Thread-48
47開始集齊東西Thread-47
46開始集齊東西Thread-46
45開始集齊東西Thread-45
44開始集齊東西Thread-44
43開始集齊東西Thread-43
42開始集齊東西Thread-42
41開始集齊東西Thread-41
集齊東西執行最後任務

**

semaphore

**
lock和 synchronized 默認是非公平鎖, 非公平鎖效率高 (可以加塞)

        Semaphore semaphore = new Semaphore(3,false);   

總結 : 信號量, 多個線程搶多個資源 可以代替 lock , synchronized
1.多個共享資源互斥使用
2.併發線程數控制
舉個例子 Semaphore semaphore = new Semaphore(3,false); 可以當停車場的車位 只有三個,
線程有6個 ,可以當做是車
semaphore.acquire(); 代表一部車佔位了,
semaphore.release(); 釋放停車位 最好放在finally裏面
值是可以伸縮的

  public class Test{
      public static void main(String[] args) throws InterruptedException {
		 final Semaphore semaphore = new Semaphore(30,true);
	        for(int i = 0 ; i < 180 ; i++){
	            new Thread(new Runnable() {
	                @Override
	                public void run() {
	                    try {
	                        semaphore.acquire();
	                        System.out.println("佔用停車位 "+ Thread.currentThread().getName());
	                        Thread.sleep(3000);
	                        System.out.println("睡三秒離開車位 "+ Thread.currentThread().getName());
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }finally {
	                        semaphore.release();
	                    }
	                }
	            }).start();
	        }
	   }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章