JUC Concurrent Programming: Simple Understanding and Use of Condition

Table of contents

1 Overview

2: Example

3: Some methods of condition


1 Overview

        Condition is essentially an interface, and Condition factors into different objects with Object monitor methods (wait, notify, and notifyAll) to get each object with multiple wait sets, by combining them with the effect of using any combination of Lock accomplish. Lock replaces the use of synchronized methods and statements, and Condition replaces the use of object monitor methods.

        Conditions (also known as condition queues or condition variables) provide a way for one thread to suspend execution ("wait") until another thread notifies that some state may now be true. Because access to this shared state information occurs in a different thread, it must be protected, so some form of lock is associated with this condition. The key property of a wait condition is that it atomically releases the associated lock and suspends the current thread, just like Object.wait.

A Condition instance is essentially bound to a lock. To obtain a Condition instance for a specific Condition instance, use its newCondition() method.

2: Example

Example 1:

       Suppose we have a finite buffer which supports put and take methods. If a take is attempted on an empty buffer, the thread will block until an item becomes available; if a put is attempted on a full buffer, the thread will block until space becomes available. We want to wait on the put thread and the take thread in separate wait sets so that we can use optimizations that only notify a single thread when an item or space in the buffer is available. This can be achieved using two Condition instances.

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

Example 2:

Suppose we require 3 threads, the first one prints A, the second one prints b, and the third one prints c, which requires execution in order

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: Some methods of condition

    • void await()

      Causes the current thread to wait until signaled or interrupted .

      boolean await(long time, TimeUnit unit)

      Causes the current thread to wait until a signal or interrupt is issued, or until the specified wait time elapses.

      long awaitNanos(long nanosTimeout)

      Causes the current thread to wait until a signal or interrupt is issued, or until the specified wait time elapses.

      void awaitUninterruptibly()

      Causes the current thread to wait until signaled.

      boolean awaitUntil(Date deadline)

      Causes the current thread to wait until a signal or interrupt is issued, or until the specified deadline elapses.

      void signal()

      Wake up a waiting thread.

      void signalAll()

      wake up all waiting threads

Guess you like

Origin blog.csdn.net/XikYu/article/details/131241167