Programación concurrente JUC: comprensión simple y uso de la condición

Tabla de contenido

1. Información general

2: Ejemplo

3: Algunos métodos de condición


1. Información general

        La condición es esencialmente una interfaz, y la condición tiene en cuenta diferentes objetos con métodos de supervisión de objetos (esperar, notificar y notificar a todos) para obtener cada objeto con varios conjuntos de espera, combinándolos con el efecto de usar cualquier combinación de Logro de bloqueo. Lock reemplaza el uso de métodos y sentencias sincronizados, y Condition reemplaza el uso de métodos de supervisión de objetos.

        Las condiciones (también conocidas como colas de condiciones o variables de condición) proporcionan una forma para que un subproceso suspenda la ejecución ("esperar") hasta que otro subproceso notifique que algún estado ahora puede ser verdadero. Debido a que el acceso a esta información de estado compartido ocurre en un subproceso diferente, debe protegerse, por lo que se asocia alguna forma de bloqueo con esta condición. La propiedad clave de una condición de espera es que libera atómicamente el bloqueo asociado y suspende el subproceso actual, al igual que Object.wait.

Una instancia de condición está esencialmente vinculada a un bloqueo. Para obtener una instancia de Condición para una instancia de Condición específica, use su método newCondition().

2: Ejemplo

Ejemplo 1:

       Supongamos que tenemos un búfer finito que admite métodos de poner y tomar. Si se intenta una toma en un búfer vacío, el subproceso se bloqueará hasta que haya un elemento disponible; si se intenta una colocación en un búfer lleno, el subproceso se bloqueará hasta que haya espacio disponible. Queremos esperar en el subproceso de colocación y el subproceso de toma en conjuntos de espera separados para que podamos usar optimizaciones que solo notifiquen a un único subproceso cuando un elemento o espacio está disponible en el búfer. Esto se puede lograr usando dos instancias de Condición.

 class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock(); try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally { lock.unlock(); }
   }

   public Object take() throws InterruptedException {
     lock.lock(); try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally { lock.unlock(); }
   }
 } 

Ejemplo 2:

Supongamos que requerimos 3 hilos, el primero imprime A, el segundo imprime b y el tercero imprime c, que requiere ejecución en orden

package com.example.juc.sale;

import com.sun.corba.se.impl.orbutil.threadpool.WorkQueueImpl;
import com.sun.corba.se.spi.orbutil.threadpool.WorkQueue;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author 
 * @Date Created in  2023/6/14 16:43
 * @DESCRIPTION:
 * @Version V1.0
 */

public class demo3 {
   public static void main(String[] args) {
      Test2 test2 = new Test2();
      new Thread(()->{
         test2.printA();
      },"A").start();
      new Thread(()->{
         test2.printB();
      },"B").start();
      new Thread(()->{
         test2.printC();
      },"C").start();
   }

   static class Test2{

      private Lock lock = new ReentrantLock();
      private Condition condition1 = lock.newCondition();
      private Condition condition2 = lock.newCondition();
      private Condition condition3 = lock.newCondition();
      private int number = 1;
      public void printA() {
         lock.lock();
         try {
            //业务,判断->执行->通知
            while (number != 1) {
               //等待
               condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + "--->A");
            //唤醒指定的人:B
            number = 2;
            condition2.signal();
         } catch (Exception e) {
            e.printStackTrace();
         } finally {
            lock.unlock();
         }
      }
      public void printB() {
         lock.lock();
         try {
            //业务,判断->执行->通知
            while (number != 2) {
               //等待
               condition2.await();
            }
            System.out.println(Thread.currentThread().getName() + "--->b");
            //唤醒指定的人:B
            number = 3;
            condition3.signal();
         } catch (Exception e) {
            e.printStackTrace();
         } finally {
            lock.unlock();
         }
      }
      public void printC() {
         lock.lock();
         try {
            //业务,判断->执行->通知
            while (number != 3) {
               //等待
               condition3.await();
            }
            System.out.println(Thread.currentThread().getName() + "--->c");
            //唤醒指定的人:B
            number = 3;
            condition1.signal();
         } catch (Exception e) {
            e.printStackTrace();
         } finally {
            lock.unlock();
         }
      }
   }
}

3: Algunos métodos de condición

    • void await()

      Hace que el subproceso actual espere hasta que sea señalado o interrumpido .

      boolean await(long time, TimeUnit unit)

      Hace que el subproceso actual espere hasta que se emita una señal o una interrupción, o hasta que transcurra el tiempo de espera especificado.

      long awaitNanos(long nanosTimeout)

      Hace que el subproceso actual espere hasta que se emita una señal o una interrupción, o hasta que transcurra el tiempo de espera especificado.

      void awaitUninterruptibly()

      Hace que el subproceso actual espere hasta que se le indique.

      boolean awaitUntil(Date deadline)

      Hace que el subproceso actual espere hasta que se emita una señal o una interrupción, o hasta que transcurra el plazo especificado.

      void signal()

      Despierta un hilo en espera.

      void signalAll()

      despertar todos los subprocesos en espera

Supongo que te gusta

Origin blog.csdn.net/XikYu/article/details/131241167
Recomendado
Clasificación