JAVA多线程基础:Condition对象

介绍

如果我们希望A线程可以控制B线程,同时B线程也可以控制A线程,那么Condition对象可以帮到我们。

业务场景

此时,我们有一个队列item,他处于多线性下面调用

  • 我们希望当item为空时,取数据的线程就会停止并等待数据添加
  • 当item从空的状态被添加了数据后,取数据的线程就能继续运行
  • 当item 满了 的时候,我们希望添加数据的线程就会停止并等待数据被提取
  • 当item由满了后第一次被取走数据,我们希望添加数据的线程就能继续运行

以上就是,取数据线程添加数据线程,根据队列中数据的“空”、“满”状态,相互协调和配合的情景

代码

现在我们用代码来实现上面的业务场景

  • 初始化各个锁和对象
    private final int length = 10;
    BlockingQueue items = new ArrayBlockingQueue(length);
    private final ReentrantLock lock = new ReentrantLock(false); //注意,这里需要使用“不公平锁”
    private final Condition notEmpty = lock.newCondition(); //不能空
    private final Condition notFUll = lock.newCondition(); //不能满
  • 向队列中放数据
   private Runnable put() {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        lock.lockInterruptibly();
                        Thread.sleep(100);
                        if (items.size() == length) {
                            notFUll.await();
                        }
                        items.add(1);
                        System.out.println("添加了一个数据,当前数据总量:" + items.size());
                        notEmpty.signal();
                        lock.unlock();
                    }
                } catch (InterruptedException e) {
                    notFUll.signal();
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
    }
  • 提取队列中的数据
   private Runnable get() {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        lock.lockInterruptibly();
                        Thread.sleep(500);
                        if (items.size() == 0) {
                            notEmpty.await();
                        }
                        items.take();
                        notFUll.signal();
                        System.out.println("提取了一个数据,当前数据总量:" + items.size());
                        lock.unlock();
                    }
                } catch (InterruptedException e) {
                    notFUll.signal();
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
    }
  • 主方法,测试用的
        Thread putThread = new Thread(test.put(), " PutThread");
        Thread getThread = new Thread(test.get(), " GetThread");
        putThread.start();
        getThread.start();
结论
  • 最后结果截图如下,2个进程相互的争夺锁资源,但是当线程出现满或者空状态时,会停止对方的线程
  • 在这里插入图片描述

常用的方法

最后,我们看一下Condition类常用的方法

  • await() : 使当前的线程等待,同时释放当前的锁,当其他线程中使用signal() 或者signalAll()方法时,线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待
  • awaitUninterruptibly():与await()方法基本相同,但是它并不会在等待过程中相应中断
  • singal() : 用于唤醒一个在等待中的线程,相对的singalAll方法会唤醒所有等待的线程。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值