Heim >Java >javaLernprogramm >Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen

php是最好的语言
php是最好的语言Original
2018-07-28 16:11:201892Durchsuche

In einem kürzlichen Interview stieß ich auf eine Frage zu den drei Synchronisierungstoolklassen von Java-Threads, an die ich mich erst erinnern konnte, als ich Multithreading lernte sorgfältig, und jetzt habe ich es sogar vergessen. Deshalb habe ich es noch einmal durchgesehen und fand es ziemlich tiefgreifend, also habe ich es zusammengestellt und einen Artikel als Referenz geschrieben. Apache PHP MySQL

Java stellt uns drei Synchronisierungstoolklassen zur Verfügung:

  • CountDownLatch (Sperre):

    Ein Thread wartet damit andere Threads die Ausführung beenden, bevor sie ausgeführt werden (andere Threads warten darauf, dass die Ausführung eines Threads abgeschlossen ist, bevor er ausgeführt wird)

  • CyclicBarrier (Barriere):

    A Eine Gruppe von Threads wartet darauf, dass einander einen bestimmten Zustand erreicht, und dann führt die Gruppe von Threads gleichzeitig aus.

  • Semaphor:

    Steuern Sie eine Gruppe von Threads zur gleichzeitigen Ausführung.

Um es ganz klar auszudrücken: Diese Toolklassen sind darauf ausgelegt, die Kommunikationsprobleme zwischen Threads besser zu kontrollieren~

1 🎜>

1.1 Einführung in CountDownLatch

  • Eine Synchronisierungshilfe, die es einem oder mehreren Threads ermöglicht, zu warten, bis eine Reihe von Vorgängen, die in anderen Threads ausgeführt werden, abgeschlossen ist.

Einfach ausgedrückt: CountDownLatch ist eine synchronisierte Hilfsklasse, die

einem oder mehreren Threads ermöglicht, zu warten , bis andere Threadsihre Operationen abgeschlossenhaben . Es gibt tatsächlich zwei häufig verwendete APIs:

und

await()countDown()

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, SammlungsnotizenGebrauchsanweisung:

    count initialisiert CountDownLatch, und dann ruft der Thread, der warten muss, die Methode „await“ auf. Die Wait-Methode blockiert, bis count=0 ist. Nachdem andere Threads ihre Vorgänge abgeschlossen haben, rufen Sie
  • auf, um den Zählerstand um 1 zu verringern.

    Wenn die Anzahl auf 0 sinkt, werden alle wartenden Threads freigegebencountDown()

  • Um es ganz klar auszudrücken: Das Warten wird durch die
  • Zählervariable

    gesteuert, If der Zählwert 0 ist (die Aufgaben anderer Threads wurden abgeschlossen), dann kann die Ausführung fortgesetzt werden.

  • 1.2 CountDownLatch-Beispiel

Beispiel: 3y arbeitet jetzt als Praktikant und die anderen Mitarbeiter sind noch nicht von der Arbeit gekommen. 3y ist zu verlegen, um zuerst zu gehen Ich warte 3 Tage vor der Abreise auf die Abreise aller anderen Mitarbeiter.

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();
        }
    }
}

Ausgabeergebnis:

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, SammlungsnotizenSchreiben Sie ein weiteres Beispiel: 3y ist jetzt für die Lagermodulfunktion verantwortlich, aber seine Fähigkeiten sind zu schlecht und er schreibt sehr langsam ,

Andere Mitarbeiter müssen warten, bis 3 Jahre abgelaufen sind, bevor sie mit dem Schreiben fortfahren können.

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();
        }
    }
}
Ausgabeergebnisse:

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen2. CyclicBarrier

2.1 Einführung in CyclicBarrier

    Eine Synchronisationshilfe, die es einer Reihe von Threads ermöglicht, aufeinander zu warten, um einen gemeinsamen Barrierenpunkt zu erreichen, ist in Programmen nützlich, die eine Gruppe fester Threads umfassen, die gelegentlich aufeinander warten müssen wird
  • zyklisch

    genannt, da es wiederverwendet werden kann, nachdem die wartenden Threads freigegeben wurden Einen öffentlichen Barrierepunkt erreichen. Es wird zyklisch genannt, weil CyclicBarrier, wenn alle wartenden Threads freigegeben sind,

    wiederverwendet werden kann
  • (im Gegensatz zu CountDownLatch, das nicht wiederverwendet werden kann)
Gebrauchsanweisung:

CountDownLatch konzentriert sich auf das Warten auf den Abschluss anderer Threads

: Wenn der Thread

einen bestimmten Status erreicht

, hält er an und wartet auf andere Threads
    Alle Threads kommen an. In Zukunft
  • , Ausführung fortsetzen.

    2.2 CyclicBarrier-BeispielBeispiel: 3y und seine Freundin haben sich zum Essen nach Guangzhou Ye Shanghai verabredet. Da 3y und die Freundin von 3y an verschiedenen Orten leben, sind sie Natürlich ging auch der Weg ein anderer. Also verabredeten sie sich an der U-Bahn-Station Tiyu West Road

    und vereinbarten, eine Nachricht an Moments zu senden, wenn sie
  • sich trafen
.

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();
        }
    }
}

Testergebnisse:

Nachdem sie einen Tag lang gespielt hatten,

kehrten alle nach Hause zurück

, 3y und seine Freundin stimmten

zu miteinander chatten nach dem Duschen

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen

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();
        }
    }
}

Testergebnis:

三、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();

        }

    }
}

输出结果:

Zusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen

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

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

相关文章:

Java基础之线程同步

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

相关视频:

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

Das obige ist der detaillierte Inhalt vonZusammenfassung der Wissenspunkte zu drei Synchronisierungstools von Java-Threads, Sammlungsnotizen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn