深入浅出java并发编程(Condition)

前言

参考链接1

package java.util.concurrent.locks
在这里插入图片描述
子类
在这里插入图片描述

public interface Condition {

    void await() throws InterruptedException;
    
    void awaitUninterruptibly();
    
    long awaitNanos(long nanosTimeout) throws InterruptedException;
       
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    
    boolean awaitUntil(Date deadline) throws InterruptedException;
    
    void signal();
    
    void signalAll();
}

实例化

ReentrantLock中

    public Condition newCondition() {
        return sync.newCondition();
    }
        final ConditionObject newCondition() {
            return new ConditionObject();
        }

Condition 配合 Lock 实现 等待和通知机制,非常类似于 wait 和 notify 方法

static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
condition.await();
condition.signal();
condition.signalAll();

await 类似于 wait, signal 类似于 notify,signalAll 类似于 notifyAll 。

condition.await() 会响应中断,标志位的变化为 false -> true -> false

在这里插入图片描述

调用线程的静态方法清除 标志位

在这里插入图片描述
超时之后自动返回 false ,超时之前被唤醒返回 true

跟 Object 中 wait 和 notify 对比

condition能够支持多个等待队列(new 多个Condition对象),而Object方式只能支持一个。

condition 可以 awaitUninterruptibly 方法 来实现 不中断等待,也就是不响应 intertupt ,只能通过 signal 来唤醒。

在这里插入图片描述

condition 可以 awaitUntil 来等待到将来的某个时间 ,会响应 中断 。

在这里插入图片描述

一个 多 Condition的例子

public class D8<E> {

    public D8(int size) {
        this.size = size;
    }

    int size;

    ReentrantLock lock = new ReentrantLock();

    LinkedList<E> list = new LinkedList<>();

    Condition add = lock.newCondition();

    Condition remove = lock.newCondition();


    public void enqueue(E e) throws InterruptedException {
        lock.lock();
        try {
            //满了等待
            while (list.size() == size) {
                add.await();
            }
            list.add(e);
            System.out.println("入队:" + e);
            remove.signal();
        } finally {
            lock.unlock();
        }
    }

    public E dequeue() throws InterruptedException {
        E e;
        lock.lock();
        try {
            //空的等待
            while (list.size() == 0) {
                remove.await();
            }
            e = list.removeFirst();
            System.out.println("出队:" + e);
            add.signal();
            return e;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        //
        D8<Integer> queue = new D8<>(2);
        //
        for (int i = 0; i < 10; i++) {
            int data = i;
            new Thread(() -> {
                try {
                    queue.enqueue(data);
                } catch (InterruptedException e) {
                }
            }
            ).start();
        }
        //
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    queue.dequeue();
                } catch (InterruptedException e) {
                }
            }
            ).start();
        }
    }
}

-------
入队:1
入队:3
出队:1
入队:7
出队:3
出队:7
入队:9
出队:9
入队:2
出队:2
入队:0
入队:4
出队:0
出队:4
入队:5
出队:5
入队:6
入队:8
出队:6
出队:8

进程已结束,退出代码为 0

链表的大小为2,有两个队列,一个是add,一个是remove,一个生产线程过来生产,如果集合满了,从生产队列上等待,如果集合没满则生产元素并唤醒消费队列的一个线程。一个消费过来消费,如果集合是空的,从消费队列上等待,如果集合不是空的,消费并唤醒生产队列的一个线程。

condition的多队列的优势,一个生产者和两个消费者,如果集合满了,会稳定唤醒消费者参与竞争,而集合为空又会稳定唤醒生产者进行竞争,而一个队列的话,会发生集合满了生产线程去等待了,notify又随机唤醒了生产线程起来做判断,发现满了之后继续等待的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值