java 다중 루틴 - 다중 루틴 동기화기

6371 단어 java 프로그래밍
1. 멀티스레드 동기화기는 무엇입니까?
다중 스레드 이전의 동기화 동작을 제어하는 도구로 이해할 수 있습니다.
2. 왜 다중 스레드 동기화기를 사용합니까?
실제 응용에서, 우리는 다중 라인이 특정한 규칙에 따라 집행되기를 바란다.따라서 다중 스레드 동기화기가 있어 서로 다른 다중 스레드 동기화기를 통해 다중 스레드가 다양한 행위를 실현할 수 있다.
3. 다중 스레드 동기화기 소개
3.1、Samaphore
응용 장면: 한 그룹에 대한 자원 접근이 제한되어 있습니다.예를 들어 식당에 두 개의 위치가 있지만 동시에 10명이 밥을 먹으려면 10명이 식당에 대한 병발 실용성을 컨트롤해야 한다.즉 자리가 비었을 때 식사를 하는 사람이 있고 비었을 때 막혀 기다리는 사람이 있다는 것이다.
사용법:Semaphore 변수 semaphore는 제한된 자원 개수를 포함하고 모든 사람이 식사하러 올 때semaphore를 호출합니다.acquire () 방법으로 식사 자리를 얻습니다. (식사 자리가 없으면 대기를 막습니다.) 식사를 마친 후semaphore를 사용합니다.release () 는 다른 사람에게 식탁을 방출한다.
package study.threadPoolTest;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SamaphoreTest {
    private static Semaphore semaphore = new Semaphore(2);

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            Person p = new Person(i);
            executorService.submit(p);
        }
        executorService.shutdown();

    }

    static class Person implements Callable {

        int i;

        Person(int i) {
            this.i = i;
        }

        @Override
        public Object call() throws Exception {
            semaphore.acquire();
            System.out.println("start:" + i);
            Thread.sleep(2000);
            System.out.println("finished:" + i);
            semaphore.release();
            return null;
        }
    }
}

결과:
semaphore의 값은 2입니다. 최대 2개의 라인만 실행됩니다.start:0 start:1 두 라인이 실행됩니다.finished:0 0번 라인이 끝났을 때만 2번 라인이 시작됩니다 start:2
start:0
start:1
finished:0
start:2
finished:1
start:3
finished:2
start:4
finished:3
start:5
finished:4
start:6
finished:5
start:7
finished:6
start:8
finished:7
start:9
finished:8
finished:9

3.2、CountDownLatch
응용 장면: 한 그룹의 스레드 작업이 완성되기를 기다린 후에 현재 스레드를 계속 실행합니다.
사용법: 현재 스레드에서 latch를 호출하는 CountDownLatch 변수 latch를 정의합니다.await () 방법, 기다리는 라인에서 실행이 끝난 후latch를 호출합니다.countDown () 방법, 이 라인이 latch를 호출했을 때.countDown () 방법 후 현재 스레드latch를 실행합니다.await () 후의 방법.
package study.threadPoolTest;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchTest {

    private static CountDownLatch countDownLatch = new CountDownLatch(2);
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        executorService.submit(new mainThread());
        for (int i = 0;i<5;i++){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println("Exception" + e);
            }
            int j = i;
            executorService.submit(() -> {
                System.out.println("start" + j);
                countDownLatch.countDown();
                System.out.println("finished " + j);

            });
        }
        executorService.shutdown();
    }
    static class mainThread implements Runnable{

        @Override
        public void run() {
            try {
                System.out.println("start");
                countDownLatch.await();
                System.out.println("finished");
            } catch (InterruptedException e) {
                System.out.println("Exception" + e);
            }
        }
    }

}

결과:
countDownLatch의 값은 2로 두 라인이 실행된 후에야 계속 실행해야 한다는 것을 나타낸다.start 메인 라인 start 이후countDownLatch.await(); start0 finished 0 start1 finished 1 두 라인이 실행되면 주 라인이finished를 계속 실행합니다
start
start0
finished 0
start1
finished 1
finished
start2
finished 2
start3
finished 3
start4
finished 4

3.3、CyclierBarrier
응용 장면: 한 그룹의 라인이 어느 지점에 도착한 후에 함께 실행되기를 기다리고 이 그룹의 라인이 지정된 지점에 도착한 후에 다시 순환해서 실행할 수 있습니다.한 조의 라인이 어느 지점에 도달한 후에 어떤 방법을 집행하는 데도 사용할 수 있다.
사용법: 라인이 일정한 지점에 도달했을 때 barrier를 호출하는 CyclicBarrier 변수 barrier를 정의합니다.await () 방법, 이 그룹의 모든 라인이barrier를 호출할 때.await () 방법 후 라인을 바꾸어 함께 아래로 실행합니다.
CyclicBarrier와 CountDownLatch의 차이
CountDownLatch 카운터는 한 번만 사용할 수 있습니다.CyclicBarrier의 카운터는 reset() 방법으로 재설정할 수 있습니다.그래서 CyclicBarrier는 더욱 복잡한 업무 장면을 처리할 수 있다. 예를 들어 계산에 오류가 발생하면 계수기를 리셋하고 라인을 다시 실행할 수 있다.CyclicBarrier는 getNumberWaiting 방법과 같이 CyclicBarrier가 막힌 라인의 수를 얻을 수 있는 다른 유용한 방법을 제공합니다.isBroken 방법은 막힌 라인이 끊겼는지 확인하는 데 사용됩니다.
package study.threadPoolTest;

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

public class CyclicBarrierTest {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        for (int i = 0;i < 10;i++){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int finalI = i;
            executorService.submit(() -> {
                try {
                    System.out.println("start" + finalI + "count=" + cyclicBarrier.getNumberWaiting());
                    cyclicBarrier.await();
                    System.out.println("finished" + finalI);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

            });
        }
        executorService.shutdown();
    }
}

결과:
CyclierBarrier의 값은 3으로 매번 스레드를 차단하고 세 개의 스레드로 차단해야 계속 실행할 수 있음을 나타낸다.또한 Cyclier Barrier는 항상 유효 start3count=0 start4count=1 start5count=2 finished5 finished3 finished4 start6count=0 start7count=1 start8count=2 finished8 finished6 finished7 start9count=0
start0count=0
start1count=1
start2count=2
finished2
finished0
finished1
start3count=0
start4count=1
start5count=2
finished5
finished3
finished4
start6count=0
start7count=1
start8count=2
finished8
finished6
finished7
start9count=0

좋은 웹페이지 즐겨찾기