Condition接口(又称条件对象)

简介: 作用- 当线程1需要等待某个条件的时候 ,它就去执行 condition.await() 方法,一旦执行了 await()方法,线程就会进入阻塞状态

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

在这里插入图片描述

#在这里插入图片描述
有兴趣的同学可以看下源码实现 和 JDK 介绍

相关文章
|
6月前
|
编译器 C语言
关系/条件/逻辑~操作符
关系/条件/逻辑~操作符
|
1月前
|
存储 算法 Java
作为Collection接口的子接口,Set不支持重复元素,也不保证元素顺序,适用于需要唯一性约束的场景。
【10月更文挑战第16天】Java的Set接口因其独特的“不重复性”而备受关注。作为Collection接口的子接口,Set不支持重复元素,也不保证元素顺序,适用于需要唯一性约束的场景。其背后的实现机制依赖于哈希表或红黑树等数据结构,通过哈希算法和equals()方法确保元素的唯一性。例如,使用HashSet可以轻松过滤重复的字符串。这种设计使Set在处理唯一数据时高效便捷。
25 3
|
3月前
|
Python
`return` 和 `yield` 关键字之间的区别
【8月更文挑战第29天】
43 5
|
6月前
|
C#
C#动态查询:巧用Expression组合多条件表达式
在C#中,利用`Expression`类和`AndAlso`、`OrElse`方法,可以组合两个`Expression<Func<T, bool>>`以实现动态多条件查询。该方法通过构建表达式树,方便地构建复杂查询。示例代码展示了如何创建表达式树,分别检查年龄大于等于18和姓名为"John"的条件,并使用`AndAlso`组合这两个条件,最终编译为可执行的委托进行测试。
256 1
|
6月前
判断是否保持函数依赖的方法
判断是否保持函数依赖的方法
101 2
|
6月前
Condition的awaitNanos&signalAll方法分析
Condition的awaitNanos&signalAll方法分析
48 6
|
前端开发
判断数组对象中是否满足某条件
判断数组对象中是否满足某条件
35 0
|
存储 安全 Java
线程安全问题的产生条件、解决方式
线程安全问题的产生条件、解决方式
73 0
|
Java
【Groovy】集合遍历 ( 调用集合的 every 方法判定集合中的所有元素是否符合闭包规则 | =~ 运算符等价于 contains 函数 | 代码示例 )
【Groovy】集合遍历 ( 调用集合的 every 方法判定集合中的所有元素是否符合闭包规则 | =~ 运算符等价于 contains 函数 | 代码示例 )
193 0
【Groovy】集合遍历 ( 调用集合的 every 方法判定集合中的所有元素是否符合闭包规则 | =~ 运算符等价于 contains 函数 | 代码示例 )