線程同步:Semaphore、CyclicBarrier、CountDownLatch

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/hfy8971613/article/details/81058054

一、Semaphore

Semaphore:信號量,用於限制某段代碼的併發數。當permits爲1,相當於synchronized。

直接上代碼:

    /**
     * test Semaphore
     * 信號量,用於限制某段代碼的併發數。
     * 當N爲1,相當於synchronized
     */
    private void threadTest5() {
        final int permits = 3;
        final Semaphore semaphore = new Semaphore(permits);

        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 5; i++) {
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    try {

                        //獲得許可
                        semaphore.acquire();
                        Log.i(TAG, "run: 剩餘許可 = " + semaphore.availablePermits());

                        Thread.sleep(2000);

                        //釋放許可
                        semaphore.release();


                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

    }

結果如下,前三條几乎同時打印,後兩條是2000ms後打印,可見併發數就是permits值

07-15 22:39:44.218 6810-7087/com.hfy.demo00 I/MainActivityhfy: run: 剩餘許可 = 2
07-15 22:39:44.220 6810-7088/com.hfy.demo00 I/MainActivityhfy: run: 剩餘許可 = 1
07-15 22:39:44.221 6810-7090/com.hfy.demo00 I/MainActivityhfy: run: 剩餘許可 = 0
07-15 22:39:46.220 6810-7089/com.hfy.demo00 I/MainActivityhfy: run: 剩餘許可 = 0

07-15 22:39:46.222 6810-7091/com.hfy.demo00 I/MainActivityhfy: run: 剩餘許可 = 1


二、CyclicBarrier

CyclicBarrier,循環柵欄,n個線程都await了,纔會 各自 繼續往下走。(計數器可被重置後使用)

    /**
     * 循環柵欄 CyclicBarrier
     * 大家都await了,才各自繼續走。
     */
    private void threadTest6() {
        final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "run: 線程全都cyclicBarrier.await()了, 那大家都可以繼續往下走了~");
            }
        });

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 4; i++) {
            final int finalI = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
//                        int numberWaiting = cyclicBarrier.getNumberWaiting();
//                        Log.i(TAG, "run: i="+ finalI + ",numberWaiting = "+ numberWaiting);
                        Log.i(TAG, "run: i=" + finalI + ",我睡1s了,cyclicBarrier.await()");
                        cyclicBarrier.await();
                        Log.i(TAG, "run: i=" + finalI + ",繼續往下走了~");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }

                }
            });
        }

    }

結果如下,0、1、2都await了(阻塞了),然後各自都可以繼續往下走了。

07-15 22:47:19.888 8140-8235/com.hfy.demo00 I/MainActivityhfy: run: i=2,我睡1s了,cyclicBarrier.await()
07-15 22:47:19.888 8140-8233/com.hfy.demo00 I/MainActivityhfy: run: i=0,我睡1s了,cyclicBarrier.await()
07-15 22:47:19.888 8140-8234/com.hfy.demo00 I/MainActivityhfy: run: i=1,我睡1s了,cyclicBarrier.await()
    run: 線程全都cyclicBarrier.await()了, 那大家都可以繼續往下走了~
    run: i=1,繼續往下走了~
07-15 22:47:19.889 8140-8233/com.hfy.demo00 I/MainActivityhfy: run: i=0,繼續往下走了~
07-15 22:47:19.890 8140-8235/com.hfy.demo00 I/MainActivityhfy: run: i=2,繼續往下走了~

07-15 22:47:19.891 8140-8236/com.hfy.demo00 I/MainActivityhfy: run: i=3,我睡1s了,cyclicBarrier.await()


三、CountDownLatch

CountDownLatch,閉鎖,我(們) 等(await) 你們都countDown了,才往下走。

    /**
     * 閉鎖 CountDownLatch
     * 我(們)await你們都countDown了,才往下走
     */
    private void threadTest7() {
        final CountDownLatch latch = new CountDownLatch(3);

        for (int i = 0; i < 5; i++) {

            ExecutorService executorService = Executors.newFixedThreadPool(10);
            final int finalI = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);

                        Log.i(TAG, "run: i=" + finalI + ",countDown了");
                        latch.countDown();

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        try {
            Log.i(TAG, "threadTest7: 主線程開始等待~");
            latch.await();
            Log.i(TAG, "threadTest7: 主線程繼續走了~");
        } catch (
                InterruptedException e)
        {
            e.printStackTrace();
        }
        
    }

結果如下:

07-15 22:52:27.064 8684-8684/com.hfy.demo00 I/MainActivityhfy: threadTest7: 主線程開始等待~
07-15 22:52:28.064 8684-8970/com.hfy.demo00 I/MainActivityhfy: run: i=2,countDown了
07-15 22:52:28.064 8684-8969/com.hfy.demo00 I/MainActivityhfy: run: i=1,countDown了
07-15 22:52:28.064 8684-8968/com.hfy.demo00 I/MainActivityhfy: run: i=0,countDown了
07-15 22:52:28.065 8684-8684/com.hfy.demo00 I/MainActivityhfy: threadTest7: 主線程繼續走了~
07-15 22:52:28.065 8684-8972/com.hfy.demo00 I/MainActivityhfy: run: i=4,countDown了
07-15 22:52:28.066 8684-8971/com.hfy.demo00 I/MainActivityhfy: run: i=3,countDown了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章