Herramientas auxiliares bajo la JUC

Prefacio

Y luego java.util.concurrentel paquete, hay varias operaciones de herramientas auxiliares. Como CountDownLatch 减法计数器, CyclicBarrier 加法计数器y Semaphore 信号量.

Me sorprendió escuchar acerca de estas categorías. Ahora hablemos sobre cómo usar estas tres categorías de herramientas.

CountDownLatch down counter

Dado el tamaño y la capacidad inicial, se llama cada vez que un subproceso realiza una operación, y la capacidad es -1. Cuando
no hay datos en él, continuará realizando otras operaciones.

Mira las siguientes castañas:

import java.util.concurrent.CountDownLatch;

/**
 * 减法  计数器;用于 必须保证所有线程都执行完后继续其他操作。
 */
public class CountDownTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 1、计数器对象的创建,并给定计数器初始大小数
        CountDownLatch countDownLatch = new CountDownLatch(6);

        // 开启多个线程执行操作
        for (int i = 1; i <= 6; i++) {
    
    
            new Thread(()->{
    
    
                System.out.println(Thread.currentThread().getName()+" get ticket");
                // 2、每个线程执行某项操作时,将计数器-1
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }

        // 3、等待计数器中的数据门票消耗完
        countDownLatch.await();
        // 4、打印信息
        System.out.println("ticket num 0");
    }
}

El resultado de la ejecución es el siguiente:
Inserte la descripción de la imagen aquí
[发现:]

Use await(), después de dejar que otros subprocesos terminen de ejecutarse, continuará esperando, un poco similar thread 中的 join(), esperará a que todos los subprocesos terminen de ejecutarse antes de continuar con otras operaciones a continuación.

Consulte el manual de desarrollo de jdk 1.8, que explica el método de la siguiente manera:
Inserte la descripción de la imagen aquí

Contador de adición de CyclicBarrier

Como se mencionó anteriormente 减法计数器, debe haberlo 加法计数器. Su funcionamiento se CyclicBarrierbasa en:.
Mira el siguiente ejemplo:

package demo5_1;

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

/**
 * 加法计数器
 */
public class CyclicBarrierDemo {
    
    
    public static void main(String[] args) {
    
    
        // 创建 10个 大小的  计数器
        //CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10,()->{
    
    
            System.out.println("票售完");
        });

        // 创建多线程
        for (int i = 1; i <= 10 ; i++) {
    
    
            new Thread(()->{
    
    
                // 打印信息
                System.out.println(Thread.currentThread().getName()+" get ticket");
                // 计数器等待
                try {
    
    
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
    
    
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

La información de impresión del registro después de la ejecución es la siguiente:
Inserte la descripción de la imagen aquí
[发现:]

1. Se define un contador de adiciones al principio y el método de construcción adoptado es el siguiente public CyclicBarrier(int parties, Runnable barrierAction).
2. Después de que cada hilo ejecute algún negocio, llámelo cyclicBarrier.await(), lo que equivale a agregarlo a la lista de monitoreo.
3, cuando el volumen establecido esté completamente ocupado, activará CyclicBarrier(int parties, Runnable barrierAction)el Runnable.

Ver await()la lógica de ejecución del código fuente :
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Semáforo

La clase de herramienta de semáforo se usa generalmente para clases de recursos limitados. Durante el
subproceso múltiple, si un número limitado de subprocesos están completamente ocupados, solo se permite que los subprocesos desocupados esperen;
cuando se libera el subproceso inicialmente ocupado, los subprocesos subsiguientes para ser utilizados.

Similar a la siguiente lógica:

Created with Raphaël 2.2.0 线程进入 开始获取座位 座位被占用? 拿到座位 yes no

Es 令牌桶muy similar a la lógica de los algoritmos. tal como请求限流!

El proceso de visualización de la imagen sigue siendo muy abstracto, mire las siguientes castañas:

package demo5_1;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 信号量:用于某资源占用,其他处理等待其他线程处理完后才能处理
 */
public class SemphoreDemo {
    
    
    public static void main(String[] args) {
    
    
        // 假设 座位只有3个
        Semaphore semaphore = new Semaphore(3);
        // 创建线程
        for (int i = 1; i <= 12 ; i++) {
    
    
            new Thread(()->{
    
    
                try {
    
    
                    // 获取座位(此处会造成阻塞   必须等待有空位才会分配,即向下执行)
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+" 获取座位");
                    // 假设拿到座位后占用2秒
                    TimeUnit.SECONDS.sleep(2);
                    // 离开座位 原则上应该放在finally中执行 --- 释放资源操作
                    //semaphore.release();
                    //System.err.println(Thread.currentThread().getName()+" 离开座位");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }finally {
    
    
                    // 离开座位 原则上应该放在finally中执行--- 释放资源操作
                    semaphore.release();
                    // 用err只是颜色区分日志打印
                    System.err.println(Thread.currentThread().getName()+" 离开座位");
                }

            },String.valueOf(i)).start();
        }
    }
}

El registro de salida de la consola después de la ejecución es el siguiente:
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_38322527/article/details/114937513
Recomendado
Clasificación