Clase de subprocesos múltiples concurrentes de JAVA (dos): comprensión y uso de la barrera de sincronización CyclicBarrier

Introducción

CyclicBarrier significa literalmente una barrera cíclica (Barrera).

Lo que tiene que hacer es bloquear un grupo de hilos cuando llegan a una barrera (también llamado punto de sincronización), y la barrera no se abrirá hasta que el último hilo alcance la barrera.

Todos los hilos interceptados por la barrera seguirán funcionando. El método de construcción predeterminado de CyclicBarrier es CyclicBarrier (int Parties) y su parámetro indica el número de subprocesos interceptados por la barrera.

Cada hilo llama al método de espera para decirle a CyclicBarrier que he alcanzado la barrera y luego se bloquea el hilo actual.

El código de ejemplo es el siguiente:

public class CyclicBarrierTest {
    static CyclicBarrier c = new CyclicBarrier(2);
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {

                }
                System.out.println(1);
            }
        }).start();

        try {
            c.await();

        } catch (Exception e) {

        }
        System.out.println(2);
    }
}
输出
-> 2
-> 1
或者输出
-> 1
-> 2
如果把new CyclicBarrier(2)修改成new CyclicBarrier(3)则主线程和子线程会永远等待,因为没有第三个线程执行await方法,即没有第三个线程到达屏障,所以之前到达屏障的两个线程都不会继续执行。

CyclicBarrier también proporciona un constructor CyclicBarrier más avanzado (int Parties, Runnable robust Barrier), que se utiliza para ejecutar primero el BarrierAction cuando el hilo alcanza la barrera, lo cual es conveniente para manejar escenarios comerciales más complejos.

 

el código se muestra a continuación:

 

public class CyclicBarrierTest2 {
    static CyclicBarrier c = new CyclicBarrier(2, new A());
    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
                System.out.println(1);
            }
        }).start();
 
        try {
            c.await();
        } catch (Exception e) {
        }
        System.out.println(2);
    }

    static class A implements Runnable {
        @Override
        public void run() {
            System.out.println(3);
        }
    }
}

=== 输出
-> 3
-> 1
-> 2

Escenarios de aplicación de CyclicBarrier

CyclicBarrier se puede utilizar para calcular datos en varios subprocesos y, finalmente, fusionar los escenarios de aplicación de los resultados del cálculo. Por ejemplo, usamos un Excel para guardar todo el flujo bancario del usuario, y cada hoja guarda cada flujo bancario de una cuenta en el último año. Ahora necesitamos contar el flujo bancario diario del usuario y primero usar el multihilo para procesar el flujo bancario en cada hoja. Una vez finalizadas todas las ejecuciones, se obtiene la facturación bancaria media diaria de cada hoja. Finalmente, la barreraAction se utiliza para calcular la facturación bancaria media diaria de todo el Excel utilizando los resultados de cálculo de estos hilos.

 

La diferencia entre CyclicBarrier y CountDownLatch 

El contador CountDownLatch solo se puede usar una vez. El contador de CyclicBarrier se puede restablecer mediante el método reset (). Por lo tanto, CyclicBarrier puede manejar escenarios comerciales más complejos. Por ejemplo, si ocurre un error en el cálculo, el contador se puede restablecer y los hilos se pueden ejecutar nuevamente.

CyclicBarrier también proporciona otros métodos útiles, como el método getNumberWaiting para obtener el número de subprocesos bloqueados por CyclicBarrier. El método isBroken se utiliza para saber si se interrumpe el hilo bloqueado. Por ejemplo, el siguiente código devolverá verdadero después de la ejecución

El código de uso de isBroken es el siguiente:

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest3 {

    static CyclicBarrier c = new CyclicBarrier(2);

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c.await();
                } catch (Exception e) {
                }
            }
        });
        thread.start();
        thread.interrupt();
        try {
            c.await();
        } catch (Exception e) {
            System.out.println(c.isBroken());
        }
    }
}


=====> 输出

 true 

 

Supongo que te gusta

Origin blog.csdn.net/bj_chengrong/article/details/108704141
Recomendado
Clasificación