ホームページ > Java > &#&チュートリアル > Javaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ

Javaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ

php是最好的语言
リリース: 2018-07-28 16:11:20
オリジナル
1897 人が閲覧しました

最近のインタビューで、Java スレッドの 3 つの同期ツール クラスに関する質問に遭遇しました。マルチスレッドを学習していたときに、同期ツール クラスを注意深く勉強しませんでした。そして今ではそれさえ忘れてしまった。そこで改めて見直してみたらなかなか奥深い内容だったので、参考までに整理して記事にしました。 apache php mysql

Java は、 3 つの同期ツール クラスを提供します:

  • CountDownLatch (ロック):

    3つの同期ツールクラス 完了後に実行されます)


  • CyclicBarrier (フェンス):

    スレッドのグループは互いに特定の状態に達するのを待ち、このスレッドのグループは同時に実行されます。 Semaphore(Semaphore):


  • 端的に言うと、これらのツール クラスは実際には

    スレッド間の通信問題をより適切に制御するためのものです
    ~

  • 1. CountDownLatch

1.1 CountDownLatch の概要

1 つ以上の同期を可能にする同期支援ツール

  • 簡単に言うと、CountDownLatch は同期ヘルパー クラスであり、

    他のスレッド

    がその操作を完了するまで
  • 1 つ以上のスレッドを待機させることができます。
実際によく使用される API は 2 つあります: await()countDown()

Javaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ使用説明:

count は CountDownLatch を初期化し、次に必要なスレッドを初期化します。 wait は await メソッドを呼び出します。 await メソッドは count=0 になるまでブロックします。他のスレッドは操作を完了した後、countDown() を呼び出してカウンターを 1 つデクリメントします。

カウントが 0 になると、待機中のスレッドはすべて解放されますawait()countDown()

Javaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ

使用说明:

  • count初始化CountDownLatch,然后需要等待的线程调用await方法。await方法会一直受阻塞直到count=0。而其它线程完成自己的操作后,调用countDown()

  • 端的に言うと、
  • count 値が 0 の場合

    (他のスレッドのタスク)、待機は count 変数によって制御されます。完了しました)))、実行を続行できます。

    1.2 CountDownLatch の例
例: 3 歳は現在インターンとして働いていますが、他の従業員はまだ仕事を終えていません。3 歳は先に帰るのが恥ずかしく、他の従業員が全員いなくなるまで待ってから退職します。

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();
        }
    }
}
ログイン後にコピー

出力結果:

別の例: 3 歳は現在ウェアハウス モジュール機能を担当していますが、彼の能力が低すぎて書き込みが非常に遅いです。Javaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ 他の従業員は 3 歳が書き込みを完了するまで待つ必要があります。書き続けます。

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();
        }
    }
}
ログイン後にコピー
出力結果:

2. CyclicBarrierJavaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ

2.1 CyclicBarrier の概要

CyclicBarrier は、すべてのスレッドが共通のバリア ポイントに到達するまで待機できるようにする同期補助です。時々相互に待機する必要がある固定サイズのスレッドが関与するプログラムでは、待機中のスレッドが解放された後に再利用できるため、バリアは
    cyclic
  • と呼ばれます。

  • グループ スレッドは、
が共通のバリア ポイント
に到達するまで、お互いを待機します。これは、待機中のスレッドがすべて解放されると、CyclicBarrier を再利用できるため、循環と呼ばれます (再利用できない CountDownLatch とは対照的に)

使用説明:

CountDownLatch は、

他のスレッドが完了するのを待つことに重点を置いています

, CyclicBarrier の焦点は、スレッド
    が特定の状態
  • に達すると、一時停止して他のスレッドを待機し、

    すべてのスレッドが到着 した後、実行を継続することです。 2.2 サイクリックバリアの例

    例: 3 歳と彼のガールフレンドは、広州イェ上海に食事に行く約束をしました。そこで、彼らは地下鉄
  • Tiyu West Road駅で
会うことに同意し、

お互いに会ったら

Momentsにメッセージを送ることに同意しました。

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();
        }
    }
}
ログイン後にコピー
テスト結果:

一日遊んだ後、

それぞれ家に帰りました

、3歳と彼のガールフレンドは、それぞれがシャワーを浴びた後にJavaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモおしゃべりすることに同意しました

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スレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモ

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

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

相关文章:

Java基础之线程同步

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

相关视频:

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

以上がJavaスレッドの3つの同期ツールに関する知識ポイントのまとめ、収集メモの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート