Clase de control de concurrencia de la programación concurrente de Java

CountDownLatch

Permita que uno o más subprocesos esperen a que otros subprocesos completen la operación.    

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

     final CountDownLatch c = new CountDownLatch(2);

        new Thread(new Runnable() {

            @Override

            public void run() {

                c.countDown();

                System.out.println("线程1执行完成");

            }

        }).start();

        new Thread(new Runnable() {

         @Override

         public void run() {

         c.countDown();

         System.out.println("线程2执行完成");

         }

        }).start();


        c.await();

        System.out.println("退出");

}

resultado:

Ejecución del hilo 1 completada

Ejecución del hilo 2 completada

abandonar

 

El constructor de CountDownLatch recibe uno, donde el parámetro de construcción n significa esperar n finalizaciones, es decir, ejecutar countDown n veces.

CyclicBarrier

Un grupo de hilos se bloquea cuando llegan a una barrera (también llamado punto de sincronización), hasta que el último hilo alcanza la barrera.    

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);

}

Cuando dos subprocesos ejecutan c.await (), significa que la barrera actual intercepta dos subprocesos. Compare los parámetros de intercepción de CyclicBarrier. Si se ha alcanzado el estándar de sincronización, los dos subprocesos continúan ejecutándose, por ejemplo: new CyclicBarrier (2); si cuenta! = 0, los dos hilos siguen esperando.

Análisis de código fuente:    

public CyclicBarrier(int parties, Runnable barrierAction) {

        if (parties <= 0) throw new IllegalArgumentException();

//在barrier被触发之前必须调用的线程数

        this.parties = parties;

        this.count = parties;

//在barrier被触发时调用action

        this.barrierCommand = barrierAction;

    }

    public CyclicBarrier(int parties) {

        this(parties, null);

}

    public int await() throws InterruptedException, BrokenBarrierException {

        try {

            return dowait(false, 0L);

        } catch (TimeoutException toe) {

            throw new Error(toe); // cannot happen

        }

    }

}

private int dowait(boolean timed, long nanos)

        throws InterruptedException, BrokenBarrierException,

               TimeoutException {

//.....

int index = --count;

            if (index == 0) {  // tripped

//....

nextGeneration();

return 0;

//....

}

trip.await();

//.....

}

    private void nextGeneration() {

        // signal completion of last generation

        trip.signalAll();

        // set up next generation

        count = parties;

        generation = new Generation();

}

Aquí es sólo un breve análisis.

Semáforo

El semáforo (semáforo) se utiliza para controlar el número de subprocesos que acceden a recursos específicos al mismo tiempo y coordina varios subprocesos para garantizar el uso razonable de recursos comunes.

El método de construcción de Semaphore Semaphore (int permisos) acepta un número entero que representa el número de licencias disponibles. Semáforo (10) significa que se permiten 10 subprocesos para obtener una licencia, es decir, el número máximo simultáneo es 10.

El método adquirir () de Semaphore adquiere una licencia y luego llama al método release () para devolver la licencia después de su uso. También puede intentar adquirir una licencia con el método tryAcquire ().    

public static void main(String[] args) {

     ExecutorService threadPool   = Executors.newFixedThreadPool(10);

     final Semaphore       s            = new Semaphore(5);

        for (int i = 0; i < 30; i++) {

            threadPool.execute(new Runnable() {

                @Override

                public void run() {

                    try {

                        s.acquire();

                        System.out.println("save data");

                        s.release();

                    } catch (InterruptedException e) {

                    }

                }

            });

        }


        threadPool.shutdown();

}

Análisis: el número máximo de subprocesos en el grupo de subprocesos actual es 10, las tareas que deben ejecutarse son 30 y el tamaño permitido de tareas que se ejecutarán al mismo tiempo es 5. Es decir, la concurrencia de ejecución de tareas se ve afectada por el número de subprocesos y permisos, aunque el número de subprocesos es 10, solo se pueden ejecutar 5 tareas al mismo tiempo.

 

Otros métodos de semáforo:

Int availablePermits (): Devuelve el número de licencias disponibles actualmente en este semáforo.

Int getQueueLength (): devuelve el número de subprocesos que esperan obtener una licencia.

Boolean hasQueuedThreads (): si algún hilo está esperando obtener una licencia.

void reducePermits (int reducción): Reduce los permisos de reducción, que es un método protegido.

Collection getQueuedThreads (): Devuelve la colección de todos los hilos que esperan obtener una licencia, es un método protegido.

Intercambiador

Intercambiador (Intercambiador) es una clase de herramienta para la colaboración entre hilos. El intercambiador se utiliza para el intercambio de datos entre hilos. Proporciona un punto de sincronización en el que dos subprocesos pueden intercambiar datos entre sí. Los dos hilos intercambian datos a través del método de intercambio. Si el primer hilo ejecuta primero el método exchange (), siempre esperará a que el segundo hilo ejecute el método de intercambio. Cuando ambos hilos alcancen el punto de sincronización, los dos hilos Puede intercambiar datos y pasar los datos producidos por este hilo a la otra parte.

public static void main(String[] args) {

final Exchanger<String> exgr = new Exchanger<String>();

ExecutorService threadPool = Executors.newFixedThreadPool(2);

threadPool.execute(new Runnable() {

@Override

public void run() {

try {

String A = "银行流水A";// A录入银行流水数据

exgr.exchange(A);

} catch (InterruptedException e) {

}

}

});


threadPool.execute(new Runnable() {

@Override

public void run() {

try {

String B = "银行流水B";// B录入银行流水数据

String A = exgr.exchange("B");

System.out.println("A和B数据是否一致:" + A.equals(B) + ",A录入的是:" + A + ",B录入是:" + B);

} catch (InterruptedException e) {

}

}

});


threadPool.shutdown();


}

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_44416039/article/details/86162827
Recomendado
Clasificación