Uso de herramientas concurrentes

One.CountDownLatch

(1. Información general

CountDownLatch se utiliza para esperar a que se completen varios subprocesos o pasos de subprocesos antes de continuar con el siguiente paso.
构造函数Pase el recuento de parámetros y, según el marco de AQS, establezca el recuento como el valor de estado interno de AQS.
Enlace: El principio y la aplicación de AQS La
Inserte la descripción de la imagen aquí
ejecución countDown()方法del conteo se reduce en uno, y el hilo se liberará solo cuando el conteo <0.
await()方法Se usa para bloquear el hilo, si necesita establecer el tiempo máximo de bloqueo del hilo, también puede usar el await(long timeout,TimeUnit unit)método con parámetros .
Inserte la descripción de la imagen aquí

(2) Código de ejemplo

package juctools;

import java.util.concurrent.CountDownLatch;

/**
 * @author 用于等待多线程完成
 */
public class CountDownLatchTest {
    
    
    private static CountDownLatch countDownLatch = new CountDownLatch(10);

    public static void main(String[] args) {
    
    
        int name = 1;
        for (int i = 0; i < 10; i++) {
    
    
            Person person = new Person(countDownLatch,name);
            new Thread(person).start();
            name++;
        }
        try {
    
    
            countDownLatch.await();
            System.out.println("所有任务均已完成!");
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    private static class Person implements Runnable {
    
    
        private CountDownLatch countDownLatch;
        private int name;

        public Person(CountDownLatch countDownLatch, int name) {
    
    
            this.countDownLatch = countDownLatch;
            this.name = name;
        }

        @Override
        public void run() {
    
    
            Thread.currentThread().setName("第"+name+"个人");
            System.out.println(Thread.currentThread().getName()+"完成任务!");
            countDownLatch.countDown();
        }
    }
}

Ejecutar captura de pantalla:
Inserte la descripción de la imagen aquí

二 .CyclicBarrier

(1. Información general

CyclicBarrier significa barrera reutilizable . Su función es bloquear temporalmente el hilo en la posición de barrera. Solo cuando el último hilo llegue a la barrera dejará que el hilo continúe ejecutándose .
El método de construcción predeterminado es CyclicBarrier(int parties), partes representa la cantidad de hilos que deben interceptarse. Al mismo tiempo, existe otro método de construcción: CyclicBarrier(int parties, Runnable barrierAction)el objeto Runnable entrante será ejecutado por el último hilo después de que todos los hilos alcancen la barrera.
Cuando se ejecuta el método de espera, indica que el hilo ha alcanzado la barrera .

(2) La diferencia entre CyclicBarrier y CountDownLatch

1. Diferentes métodos de conteo para determinar la interceptación de hilos

CyclicBarrier implementa el recuento de sumas ejecutando el método de espera, y
CountDownLatch es el recuento de sustracciones.

2. ¿Es reutilizable?

CyclicBarrier puede restablecer el contador mediante el método reset (), pero
CountDownLatch no se puede restablecer.

3. Diferentes funciones ampliadas

Además de los métodos básicos como los métodos de espera y construcción, CyclicBarrier también proporciona métodos útiles como el método getNumberWaiting (para obtener el número de subprocesos actualmente bloqueados).

(3) Código de ejemplo

package juctools;

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

/**
 * @author CyclicBarrier
 */
public class CyclicBarrierTest {
    
    
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Last());

    public static void main(String[] args) {
    
    
        for (int i = 1; i <= 10; i++) {
    
    
            new Thread(new Person(cyclicBarrier,i)).start();
        }
        try {
    
    
            Thread.currentThread().join();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 业务对象Person
     */
    private static class Person implements Runnable {
    
    
        private CyclicBarrier cyclicBarrier;
        private int name;

        public Person(CyclicBarrier cyclicBarrier, int name) {
    
    
            this.cyclicBarrier = cyclicBarrier;
            this.name = name;
        }

        @Override
        public void run() {
    
    
            System.out.println("第"+name+"个人已经到达!");
            try {
    
    
                cyclicBarrier.await();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
    
    
                e.printStackTrace();
            }
        }
    }

    /**
     * 所有线程到达之后执行的对象
     */
    private static class Last implements Runnable {
    
    
        @Override
        public void run() {
    
    
            System.out.println("所以人均已到达!出发!");
        }
    }
}

Captura de pantalla del efecto:
Inserte la descripción de la imagen aquí

三 .Semaforo

(1. Información general

El papel de la clase Semaphore es controlar el número máximo de subprocesos que ejecutan simultáneamente un determinado negocio.
El método de construcción es Semaphore(int permits), permisos indica el número máximo de subprocesos permitidos para la ejecución concurrente, llame al acquire()método para obtener la licencia de ejecución de subprocesos y llame release()方法para devolver la licencia después de su uso .

(2) Código de ejemplo

Tome el grupo de subprocesos como ejemplo:

package juctools;

import java.util.concurrent.*;

/**
 * @author Semaphore
 */
public class SemaphoreTest {
    
    
    /**
     *共有10个线程
     */
    private static final int count = 10;
    /**
     *最多发放2个许可证
     */
    private static Semaphore s = new Semaphore(2);
    /**
     *手动创建线程池
     */
    static ThreadPoolExecutor tpe = new ThreadPoolExecutor(6,12,2,
            TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(3));

    private static class MyRunnable implements Runnable {
    
    
        private int index;

        public MyRunnable(int index) {
    
    
            this.index = index;
        }

        @Override
        public void run() {
    
    
            try {
    
    
                s.acquire();
                System.out.println("线程"+index+"获得许可,开始进入!");
                s.release();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
    
    
        for (int i = 1; i <= count; i++) {
    
    
            tpe.execute(new MyRunnable(i));
        }
        tpe.shutdown();
    }
}

Supongo que te gusta

Origin blog.csdn.net/m0_46550452/article/details/107591269
Recomendado
Clasificación