>Java >java지도 시간 >Java 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트

Java 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트

php是最好的语言
php是最好的语言원래의
2018-07-28 16:11:201892검색

최근 인터뷰에서 Java 스레드의 세 가지 동기화 도구 클래스에 대한 질문을 접했습니다. 저는 멀티스레딩을 배울 때 동기화 도구 클래스를 자세히 공부하지 않았습니다. 이제는 그 일조차 잊어버렸습니다. 그래서 다시 검토해보니 꽤 심오한 내용이라 정리해서 참고용으로 글을 쓰게 되었습니다. Apache php mysql

Java는 세 가지 동기화 도구 클래스를 제공합니다.

  • CountDownLatch(잠금):

                                       ~ 세 가지 동기화 도구 클래스가 완료된 후 실행됩니다.)

  • CyclicBarrier(울타리):

    ​​​​​​스레드 그룹은 서로 특정 상태에 도달할 때까지 기다리며, 이 스레드 그룹은 동시에 실행됩니다. ㅋㅋㅋ >

  • 솔직히 말하면 이러한 도구 클래스는 실제로

    스레드 간의 통신 문제를 더 잘 제어하기 위한 것입니다

    ~

    1. CountDownLatch
1.1 CountDownLatch 소개

하나 이상의 동기화 지원

    간단히 말하면 CountDownLatch는
  • 다른 스레드

    가 완료

    될 때까지 하나 이상의 스레드가
  • 기다릴 수 있도록 하는 동기화된 도우미 클래스입니다.
실제로 일반적으로 사용되는 두 가지 API가 있습니다: await()countDown()

Java 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트사용 지침:

count는 CountDownLatch를 초기화한 다음 필요한 스레드를 초기화합니다. 대기 호출 대기 방법. wait 메서드는 count=0이 될 때까지 차단됩니다. 다른 스레드는 작업을 완료한 후 countDown()을 호출하여 카운터를 1씩 감소시킵니다.

count가 0으로 줄어들면 모든 대기 스레드가 해제됩니다await()countDown()

Java 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트

使用说明:

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

  • 직접 말하면
  • count 변수

    를 통해 대기를 제어합니다. count 값이 0(다른 스레드의 작업)입니다. 완료) ), 계속해서 실행할 수 있습니다.

  • 1.2 CountDownLatch 예시

예: 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 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트2. CyclicBarrier

2.1 CyclicBarrier 소개

    스레드 집합이 서로 공통 장벽 지점에 도달할 때까지 기다릴 수 있도록 하는 동기화 보조 장치입니다. 때때로 서로를 기다려야 하는 고정된 크기의 스레드 파티와 관련된 프로그램에 유용합니다. 대기 스레드가 해제된 후에 다시 사용할 수 있기 때문에 장벽을
  • 주기적

    이라고 합니다.

간단히 말하면: CyclicBarrier는 다음을 허용합니다. 그룹 스레드는
공통 장벽 지점

에 도달할 때까지 서로를 기다립니다. 모든 대기 스레드가 해제되면 CyclicBarrier를 재사용할 수 있기 때문에 순환이라고 합니다 (재사용할 수 없는 CountDownLatch와 대조적) 사용 지침:

    CountDownLatch는
  • 다른 스레드가 완료될 때까지 기다리는 데 중점을 둡니다

    , CyclicBarrier는 스레드 가 특정 상태 에 도달하면 일시 중지하고 모든 스레드가 도착 한 후에 실행이 계속된다는 점에 중점을 둡니다.

  • 2.2 순환 장벽 예시

예: 3세와 여자 친구는 광저우 예상하이로 식사를 하기로 약속했습니다. 3세와 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();
        }
    }
}
테스트 결과:

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으로 문의하세요.