并发编程系列之掌握Condition接口使用

举报
yd_273762914 发表于 2021/12/02 22:13:38 2021/12/02
【摘要】 并发编程系列之掌握Condition接口使用 1、什么是Condition接口 Condition是jdk的juc包中提供的并发等待api,俗称条件等待,条件变量,用于在Lock中提供synchron...

并发编程系列之掌握Condition接口使用

1、什么是Condition接口

Condition是jdk的juc包中提供的并发等待api,俗称条件等待,条件变量,用于在Lock中提供synchronized加Object的wait/notify等待通知模式。

注意,Condition只是一个api接口,具体实现还是依赖于具体的lock类,比如使用new ReentrantLock().newCondition();

  • Object中的wait()notify()notifyAll()和synchronized配合使用,可以唤醒一个或者全部
  • Condition需要和lock实现类配合使用,一个Lock实例可以创建多个Condition,一个条件一个等待集合,可根据条件精确控制等待线程

多线程读取队列,写入数据后,唤醒读取线程继续执行。读取数据后,唤醒写线程继续执行
在这里插入图片描述

2、Condition接口常用方法

用idea编辑器查看Condition方法,如图:
在这里插入图片描述

  • await():当前线程在接到信号或被中断之前一直处于等待状态
  • await(long time, TimeUnit unit):当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • awaitNanos(long nanosTimeout):当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。
  • awaitUninterruptibly():当前线程在接到信号之前一直处于等待状态。该方法对中断不敏感
  • awaitUntil(Date deadline):当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。
  • signal():唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。
  • signal()All:唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。

2、Condition例子

利用Condition实现生产者消费者模式:


import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionLockQueue {

    private LinkedList<Object> queue;
    private volatile int capacity;
    private Condition productCondition = null;
    private Condition consumeCondition = null;
    private Lock lock;

    public ConditionLockQueue(int capacity) {
        this.queue = new LinkedList<Object>();
        this.capacity = capacity;
        lock = new ReentrantLock();
        this.productCondition  = lock.newCondition();
        this.consumeCondition = lock.newCondition();
    }

    public void put(Object obj) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == capacity) {
                productCondition.await();
                System.out.println("产品仓库满了,不能生产!");
            }
            queue.add(obj);
            System.out.println("[Producer]: " + obj+ ",共有:"+queue.size());
            consumeCondition.signal();
        } finally {
            lock.unlock();
        }
    }

    public Object sub() throws InterruptedException {
        Object obj = null;
        lock.lock();
        try {
            while (queue.size() == 0) {
                consumeCondition.await();
                System.out.println("没有产品了,需要生产!");
            }
            Object prod =  queue.remove(0);
            System.out.println("[Consumer]: " + prod + ",共有:"+queue.size());
            productCondition.signal();
        }finally {
            lock.unlock();
        }
        return obj;
    }

    public boolean isEmpty() {
        return (queue.size() == 0);
    }


    public static void main(String[] args) throws InterruptedException {
        Random random = new Random();
        ConditionLockQueue queue = new ConditionLockQueue(10);
        Runnable produceTask = () -> {
            for (; ;) {
                try {
                    queue.put(random.nextInt(10));
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable consumeTask = () -> {
            for (; ;) {
                try {
                    queue.sub();
                    Thread.sleep(random.nextInt(100));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        //3个生产者
        new Thread(produceTask).start();
        new Thread(produceTask).start();
        new Thread(produceTask).start();
        //3个消费者
        new Thread(consumeTask).start();
        new Thread(consumeTask).start();
        new Thread(consumeTask).start();

    }

}



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

附录参考资料

文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。

原文链接:smilenicky.blog.csdn.net/article/details/121672160

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。