Condition接口(又称条件对象)

@[toc]

1.作用

  • 当线程1需要等待某个条件的时候 ,它就去执行 condition.await() 方法,一旦执行了 await()方法,线程就会进入阻塞状态
  • 然后通常会有另外一个线程,假设是线程2,去执行对应的条件,知道这个条件成立,线程2就会去执行condition.signal() 方法,这是 JVM 就会被从阻塞的线程里找到那些等待该condition的线程,当线程1就会收到可执行信号的时候,他的线程状态就会变成Runnable 可执行状态

signalAll() 和signal() 区别
: signalAll() 会唤醒所有的正在等待的线程
: 但是signal是公平的,只会唤起那个等待时间最长的线程

package com.yxl.task;


import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 演示demo
 */
public class ConditionDemo {

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    //方法1
    void method1(){
        lock.lock();
        try {
            System.out.println("条件不满足,开始await");
            condition.await();
            System.out.println("条件满足了,开始执行后续");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    //方法2
    void method2() {
        lock.lock();
        try {
            System.out.println("准备工作完成,唤醒其他线程 ");
            condition.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionDemo conditionDemo =new ConditionDemo();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(1000);
                conditionDemo.method2();
            }
        }).start();
        conditionDemo.method1();
    }
}

执行结果:

条件不满足,开始await

准备工作完成,唤醒其他线程
条件满足了,开始执行后续

2.代码演示

  • 生产着消费者案例
package com.yxl.task;


import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;
import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 实现生产者 消费者
 */
public class ConditionDemo {

    private int queueSize = 10 ;
    //队列
    private PriorityQueue queue =new PriorityQueue(queueSize);
    //lock锁
    private ReentrantLock lock = new ReentrantLock();

    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    //方法1
    class Consumer extends Thread {
        @SneakyThrows
        @Override
        public void run() {
            comsume();
        }
        private void comsume() throws InterruptedException {
            while (true){
                lock.lock();
                try {
                    while (queue.size() == 0) {
                        System.out.println("队列空,等待数据");
                        notEmpty.await();
                    }
                    queue.poll();
                    notFull.signalAll();
                    System.out.println("从队列里驱走了一个数据,剩下"+ queue.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }
    }


    class Produce extends Thread {
        @SneakyThrows
        @Override
        public void run() {
            produce();
        }
        private void produce() throws InterruptedException {
            while (true){
                lock.lock();
                try {
                    while (queue.size() == queueSize) {
                        System.out.println("队列满,等待空闲");
                        notFull.await();
                    }
                    queue.offer(1);
                    notEmpty.signalAll();
                    System.out.println("向队列插入一个元素"+ queue.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }
    }

    public static void main(String[] args) {
        ConditionDemo conditionDemo =new ConditionDemo();
        Produce produce = conditionDemo.new Produce();
        Consumer consumer = conditionDemo.new Consumer();
        consumer.start();
        produce.start();
    }
}

Condition接口(又称条件对象)

#Condition接口(又称条件对象)
有兴趣的同学可以看下源码实现 和 JDK 介绍

上一篇:手写类似dubbo的rpc框架第二章《netty通信》


下一篇:根据twitter的snowflake算法生成唯一ID