多線程同步的三大神器

本文出自
代碼大溼
代碼大溼java

實現多個線程同步通常有三種方式(CountDownLatch,CyclicBarrier,Semaphore)多線程

1:CountDownLatch通常用於一個線程等待其餘多個線程的同步。其countDown方法將計數器減1。await方法在計數器不爲0的時候都是阻塞狀態(await不改變計數器的值)。
 
 2:CyclicBarrier的await將計數器值加1,其值不爲構造器中的參數的時候是阻塞的。並且CyclicBarrier還能夠重複利用。等到計數器爲0的時候開始執行。
 
3: Semaphore(信號量)是實現多線程的資源共享。

看CountDownLatch的例子:
package demo;

import java.util.concurrent.CountDownLatch;

public class Main {

    public static void main(String[] args) {
        CountDownLatch countDownLatch=new CountDownLatch(5);
        for(int i=0;i<5;i++){
            new Thread(new r(countDownLatch)).start();
        }
        try {
            countDownLatch.await();
            System.out.println("主線程能夠執行了");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

//CountDownLatch實現同步
class r implements Runnable{
    private CountDownLatch countDownLatch;
 
    public r(CountDownLatch countDownLatch){
        this.countDownLatch=countDownLatch;
    }
    @Override
    public void run() {
        System.out.println("進程  "+Thread.currentThread().getName()+"正在執行");
        try {
            Thread.sleep(3000);
            System.out.println("進程  "+Thread.currentThread().getName()+"執行完");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
}

結果
這裏寫圖片描述iide

以上是主線程等到其它5個線程都執行完成了,而後再執行。ui

接下來看CyclicBarrier(迴環刪欄)。其await方法將計數器加1,在計數器的值不是構造參數中的值的時候是阻塞狀態。等到計數器爲10開始執行。能夠等待多個線程達到同一狀態而後進行後面的任務。下面直接看例子:
public class Main {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier=new CyclicBarrier(5);
        for(int i=0;i<5;i++){
            new Thread(new r_Cyclic(cyclicBarrier)).start();
        }
    }
}


//CyclicBarrier實現同步
class r_Cyclic implements Runnable{
    private CyclicBarrier cyclicBarrier;
    public r_Cyclic(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier=cyclicBarrier;
    }
    @Override
    public void run() {
        System.out.println("進程" +Thread.currentThread().getName()+"開始執行");
        try {
            Thread.sleep(2000);
            System.out.println("進程" +Thread.currentThread().getName()+"開始等待");
            cyclicBarrier.await();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("進程" +Thread.currentThread().getName()+"執行完");
        
        
    }
    
}

結果
這裏寫圖片描述this

接下來看Semaphore(信號量)。。有8個任務,可是隻有5個資源
public class Main {

    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(5);
        //8個任務,可是隻有5個資源
        for(int i=0;i<8;i++){
            new Thread(new r_sema(semaphore)).start();
        }
    }
}

//Semaphore(信號量)實現資源共享
class r_sema implements Runnable{
   private Semaphore semaphore;
   public  r_sema(Semaphore semaphore) {
       this.semaphore=semaphore;
   }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        
        try {
            //得到一個許可
            semaphore.acquire();
            System.out.println("進程 "+Thread.currentThread().getName()+"正在執行任務");
            Thread.sleep(4000);
            
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("進程 "+Thread.currentThread().getName()+"釋放一個許可");
        //釋放一個許可
        semaphore.release();
        }
}

結果.net

這裏寫圖片描述

本文出自
代碼大溼
代碼大溼線程

歡迎與廣大 coder 交流技術
QQ:1228935432
WX:WX1228935432
這裏寫圖片描述code

相關文章
相關標籤/搜索