併發-6-wait、notify、Semaphore、CountDownLatch、CyclicBarrier

wait()、notify()和notifyAll()是Object類中的方法:

  爲何wait()等方法是在Object中而不是Thread中呢?bash

  同理,wait(),notify()是對等待這個Object(鎖)的線程進行阻塞,喚醒等操做的,固然也要放在Object中ide

  假設,wait(),notify()放在Thead中,那麼Thread可能等待不少個鎖,操做起來也很複雜ui

  若是調用某個對象的wait()方法,當前線程必須擁有這個對象的monitor(即鎖),所以調用wait()方法必須在同步塊或者同步方法中進行(synchronized塊或者synchronized方法)this

  調用某個對象的wait()方法,至關於讓當前線程交出此對象的monitor,而後進入等待狀態,等待後續再次得到此對象的鎖(Thread類中的sleep方法使當前線程暫停執行一段時間,從而讓其餘線程有機會繼續執行,但它並不釋放對象鎖)spa

  一樣地,調用某個對象的notify()方法,當前線程也必須擁有這個對象的monitor,所以調用notify()方法必須在同步塊或者同步方法中進行(synchronized塊或者synchronized方法)線程

進階一信號量

  Java 提供了經典信號量(Semaphore)的實現,經過控制必定數量的容許(permit)的方式,來達到限制通用資源訪問的目的。   你能夠想象一下這個場景,在車站、機場等出租車時,當不少空出租車就位時,爲防止過分擁擠,調度員指揮排隊,等待坐車的隊伍一次進來5我的上車, 等這5我的坐車出發,再放進去下一批 當信號量的大小爲1時,與synchronized沒有區別code

public class SemaphoreTest {
    private static Semaphore semaphore = new Semaphore(5);

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new CarWorker(semaphore).start();
        }
    }
}

class CarWorker extends Thread {
    private Semaphore semaphore;

    public CarWorker(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            out.println(Thread.currentThread() + " waiting permitted");
            semaphore.acquire();
            out.println(Thread.currentThread() + " on car !");
            Thread.sleep(10000);
        } catch (Exception e) {
        } finally {
            out.println(Thread.currentThread() + " release permitted");
            semaphore.release();
        }
    }
}
複製代碼

進階-CountDownLatch

  一次性使用的計數器,當CountDownLatch中數值爲0時,全部await的線程獲得喚醒   特別適合於A線程須要等待B和C線程的結果做爲參數的這種場景   對象

public class CountDownLatchTest {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 5; i++) {
            new FirstBatchPassenger(countDownLatch).start();
        }

        for (int i = 0; i < 5; i++) {
            new SecondBatchPassenger(countDownLatch).start();
        }

        while (countDownLatch.getCount() != 1) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        out.println("MainThread countDown!");
        countDownLatch.countDown();
    }
}

class FirstBatchPassenger extends Thread {
    private CountDownLatch countDownLatch;

    public FirstBatchPassenger(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        out.println("FirstBatchPassenger Executed!");
        countDownLatch.countDown();
    }
}

class SecondBatchPassenger extends Thread {
    private CountDownLatch countDownLatch;

    public SecondBatchPassenger(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        try {
            countDownLatch.await();
            out.println("SecondBatchPassenger Executed!");
        } catch (InterruptedException e) {
        }
    }
}
複製代碼

輸出:資源

FirstBatchPassenger Executed!
FirstBatchPassenger Executed!
FirstBatchPassenger Executed!
FirstBatchPassenger Executed!
FirstBatchPassenger Executed!
MainThread countDown!
SecondBatchPassenger Executed!
SecondBatchPassenger Executed!
SecondBatchPassenger Executed!
SecondBatchPassenger Executed!
SecondBatchPassenger Executed!
複製代碼

進階三-CyclicBarrier

觸發屏障,當await自動達到屏障數量時,觸發屏障操做。可重複使用!get

public class CyclicBarrierTest {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> out.println("Action GO!"));
        for (int i = 0; i<6;i++){
            new CyclicBarrierWorker(cyclicBarrier).start();
        }
    }
}

class CyclicBarrierWorker extends Thread {
    private CyclicBarrier cyclicBarrier;
    public CyclicBarrierWorker(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        out.println("Executed!");
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
        } catch (BrokenBarrierException e) {
        }
    }
}
複製代碼

輸出:

Executed!
Executed!
Executed!
Action GO!
Executed!
Action GO!
Executed!
Executed!
Action GO!
複製代碼
相關文章
相關標籤/搜索