JUC并发编程:Condition的简单理解与使用

目录

1:概述

2:举例

3:condition 的一些方法


1:概述

        Condition本质上是一个接口,Condition因素与Object监视器方法( wait , notify和notifyAll )成不同的对象,以得到具有多个等待集的每个对象,通过将它们与使用任意的组合的效果Lock个实现。 Lock替换synchronized方法和语句的使用, Condition取代了对象监视器方法的使用。

        条件(也称为条件队列或条件变量 )为一个线程暂停执行(“等待”)提供了一种方法,直到另一个线程通知某些状态现在可能为真。 因为访问此共享状态信息发生在不同的线程中,所以它必须被保护,因此某种形式的锁与该条件相关联。 等待条件的关键属性是它原子地释放相关的锁并挂起当前线程,就像Object.wait 。

一个Condition实例本质上绑定到一个锁。 要获得特定Condition实例的Condition实例,请使用其newCondition()方法。

2:举例

例1:

       假设我们有一个有限的缓冲区,它支持put和take方法。 如果在一个空的缓冲区尝试一个take ,则线程将阻塞直到一个项目可用; 如果put试图在一个完整的缓冲区,那么线程将阻塞,直到空间变得可用。 我们希望在单独的等待集中等待put线程和take线程,以便我们可以在缓冲区中的项目或空间可用的时候使用仅通知单个线程的优化。 这可以使用两个Condition实例来实现。

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

例子2:

假设我们要求3个线程,第一个打印A,第二个线程打印b ,第三个线程打印c,要求按照顺序执行

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:condition 的一些方法

    • void await()

      导致当前线程等到发信号或 interrupted

      boolean await(long time, TimeUnit unit)

      使当前线程等待直到发出信号或中断,或指定的等待时间过去。

      long awaitNanos(long nanosTimeout)

      使当前线程等待直到发出信号或中断,或指定的等待时间过去。

      void awaitUninterruptibly()

      使当前线程等待直到发出信号。

      boolean awaitUntil(Date deadline)

      使当前线程等待直到发出信号或中断,或者指定的最后期限过去。

      void signal()

      唤醒一个等待线程。

      void signalAll()

      唤醒所有等待线程

猜你喜欢

转载自blog.csdn.net/XikYu/article/details/131241167