首頁 >Java >java教程 >Java線程的三個同步工具類知識點的匯總,收藏備忘

Java線程的三個同步工具類知識點的匯總,收藏備忘

php是最好的语言
php是最好的语言原創
2018-07-28 16:11:201880瀏覽

最近面試中遇到Java線程的三個同步工具類的問題,沒有複習一時還真想不起來,學多線程的時候也沒有仔細學習同步工具類,現在更是忘了。因此我又重溫了一遍感覺挺高深的,為了備忘就整理了一下寫篇文章,供大家參考。 apache php mysql

Java為我們提供了三個同步工具類別

  • ##CountDownLatch(閉鎖):

                 個執行緒等待其他執行緒執行完畢後,它才執行(其他執行緒等待某個執行緒執行完畢後,它才執行)


  • #CyclicBarrier(柵欄):

                 一組執行緒互相等待至某個狀態,而這組執行緒再同時執行。


  • Semaphore(信號量):

                 控制一組執行緒同時執行。


這幾個工具類別其實說白了就是為了能夠

更好控制執行緒之間的通訊問題~

一、 CountDownLatch

1.1CountDownLatch簡介

  • A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes

#簡單來說:CountDownLatch是一個同步的輔助類,
允許一個或多個執行緒一直等待

直到其它執行緒完成它們的操作。 它常用的API其實就兩個:

await()

countDown()

Java線程的三個同步工具類知識點的匯總,收藏備忘使用說明:

    count初始化CountDownLatch,然後需要等待的執行緒呼叫await方法。 await方法會一直受阻塞直到count=0。而其它執行緒完成自己的操作後,呼叫
  • countDown()

    使計數器count減1。 當count減到0時,所有在等待的執行緒都會被釋放

  • 說白了就是透過
  • count變數來控制等待

    ,如果count值為0了(其他執行緒的任務都完成了),那就可以繼續執行。

  • 1.2CountDownLatch範例

範例:3y現在去做實習生了,其他的員工還沒下班,3y不好意思先走,等其他的員工都走光了,3y再走。

import java.util.concurrent.CountDownLatch;

public class Test {

    public static void main(String[] args) {

        final CountDownLatch countDownLatch = new CountDownLatch(5);

        System.out.println("现在6点下班了.....");

        // 3y线程启动
        new Thread(new Runnable() {
            @Override
            public void run() {
           
                try {
                    // 这里调用的是await()不是wait()
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("...其他的5个员工走光了,3y终于可以走了");
            }
        }).start();

        // 其他员工线程启动
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("员工xxxx下班了");
                    countDownLatch.countDown();
                }
            }).start();
        }
    }
}

輸出結果:

Java線程的三個同步工具類知識點的匯總,收藏備忘再寫範例:3y現在負責倉庫模組功能,但是能力太差了,寫得很慢,

別的員工都需要等3y寫好了才能繼續往下寫。

import java.util.concurrent.CountDownLatch;

public class Test {

    public static void main(String[] args) {

        final CountDownLatch countDownLatch = new CountDownLatch(1);

        // 3y线程启动
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("3y终于写完了");
                countDownLatch.countDown();

            }
        }).start();

        // 其他员工线程启动
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("其他员工需要等待3y");
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("3y终于写完了,其他员工可以开始了!");
                }
            }).start();
        }
    }
}
輸出結果:

Java線程的三個同步工具類知識點的匯總,收藏備忘二、CyclicBarrier

2.1CyclicBarrier簡介

    #A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.  CyclicBarriers are useful in programs involving a fixed sized party of 是詞called
  • cyclic

    because it can be re-used after the waiting threads are released.

簡單來說:CyclicBarrier允許一組線程互相等待,直到
到達某個公共屏障點

。叫做cyclic是因為當所有等待執行緒都被釋放以後,CyclicBarrier可以被重用(對比於CountDownLatch是不能重用的)使用說明:

    CountDownLatch注重的是
  • 等待其他線程完成

    ,CyclicBarrier注重的是:當線程到達某個狀態後,暫停下來等待其他線程,所有線程都到達以後,繼續執行。

  • 2.2CyclicBarrier例子

範例:3y和女朋友約了去廣州夜上海吃東西,由於3y和3y女朋友住的地方不同,自然去的路徑也就不一樣了。於是他倆約定在體育西路地鐵站

集合

,約定等到互相見面的時候就發一條朋友圈。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Test {

    public static void main(String[] args) {

        final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
        for (int i = 0; i < 2; i++) {

            new Thread(() -> {

                String name = Thread.currentThread().getName();
                if (name.equals("Thread-0")) {
                    name = "3y";
                } else {
                    name = "女朋友";
                }
                System.out.println(name + "到了体育西");
                try {

                    // 两个人都要到体育西才能发朋友圈
                    CyclicBarrier.await();
                    // 他俩到达了体育西,看见了对方发了一条朋友圈:
                    System.out.println("跟" + name + "去夜上海吃东西~");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
測試結果:

Java線程的三個同步工具類知識點的匯總,收藏備忘玩了一天以後,

各自回到家裡

,3y和女朋友約定各自洗澡完再聊天

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Test {

    public static void main(String[] args) {

        final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
        for (int i = 0; i < 2; i++) {

            new Thread(() -> {

                String name = Thread.currentThread().getName();
                if (name.equals("Thread-0")) {
                    name = "3y";
                } else {
                    name = "女朋友";
                }
                System.out.println(name + "到了体育西");
                try {

                    // 两个人都要到体育西才能发朋友圈
                    CyclicBarrier.await();
                    // 他俩到达了体育西,看见了对方发了一条朋友圈:
                    System.out.println("跟" + name + "去夜上海吃东西~");

                    // 回家
                    CyclicBarrier.await();
                    System.out.println(name + "洗澡");

                    // 洗澡完之后一起聊天
                    CyclicBarrier.await();

                    System.out.println("一起聊天");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
測試結果:

三、Semaphore

3.1Semaphore简介

Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource.

  • A counting semaphore.  Conceptually, a semaphore maintains a set of permits.  Each {@link #acquire} blocks if necessary until a permit is available, and then takes it.  Each {@link #release} adds a permit,potentially releasing a blocking acquirer.However, no actual permit objects are used; the {@code Semaphore} just

keeps a count of the number available and acts accordingly.

Semaphore(信号量)实际上就是可以控制同时访问的线程个数,它维护了一组"许可证"

  • 当调用acquire()方法时,会消费一个许可证。如果没有许可证了,会阻塞起来

  • 当调用release()方法时,会添加一个许可证。

  • 这些"许可证"的个数其实就是一个count变量罢了~

3.2Semaphore例子

3y女朋友开了一间卖酸奶的小店,小店一次只能容纳5个顾客挑选购买,超过5个就需要排队啦~~~

import java.util.concurrent.Semaphore;

public class Test {

    public static void main(String[] args) {

        // 假设有50个同时来到酸奶店门口
        int nums = 50;

        // 酸奶店只能容纳10个人同时挑选酸奶
        Semaphore semaphore = new Semaphore(10);

        for (int i = 0; i < nums; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    // 有"号"的才能进酸奶店挑选购买
                    semaphore.acquire();

                    System.out.println("顾客" + finalI + "在挑选商品,购买...");

                    // 假设挑选了xx长时间,购买了
                    Thread.sleep(1000);

                    // 归还一个许可,后边的就可以进来购买了
                    System.out.println("顾客" + finalI + "购买完毕了...");
                    semaphore.release();



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

        }

    }
}

输出结果:

Java線程的三個同步工具類知識點的匯總,收藏備忘

反正每次只能5个客户同时进酸奶小店购买挑选。

总结:本文简单的介绍了一下Java多线程的三个同步工具类的用处以及如何用,要深入还得看源码或者查阅其他的资料。如果文章有错的地方欢迎指正,大家互相交流。

相关文章:

Java基础之线程同步

关于Java线程同步和同步方法的详解

相关视频:

Java多线程与并发库高级应用视频教程

以上是Java線程的三個同步工具類知識點的匯總,收藏備忘的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn