Java Condition条件变量提高线程通信效率

作者:cuisuqiang 时间:2022-11-26 13:32:46 

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样

在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现。

条件变量类似JDK1.4或以前版本中的 Object.wait(); Object.notify(); Object.notifyAll();

值得注意的是当condition.await()时,隐式的将条件变量关联的Lock解锁,而使其他线程有机会获得Lock,而检查条件,并在条件满足时,等待在条件变量上。

示例代码,ArrayBlockingQueue源码摘取:


/** Main lock guarding all access */
private final ReentrantLock lock;
/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;
/**
* Inserts the specified element at the tail of this queue, waiting
* for space to become available if the queue is full.
*
* @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
 while (count == items.length)
 notFull.await();
} catch (InterruptedException ie) {
 notFull.signal(); // propagate to non-interrupted thread
 throw ie;
}
insert(e);
} finally {
lock.unlock();
}
}
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
 while (count == 0)
 notEmpty.await();
} catch (InterruptedException ie) {
 notEmpty.signal(); // propagate to non-interrupted thread
 throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}

有多个线程往里面存数据和从里面取数据,其队列(先进先出后进后出)能缓存的最大数值是capacity,多个线程间是互斥的,当缓存队列中存储的值达到capacity时,将写线程阻塞,并唤醒读线程,当缓存队列中存储的值为0时,将读线程阻塞,并唤醒写线程
这就是多个Condition的强大之处,假设缓存队列中已经存满,那么阻塞的肯定是写线程,唤醒的肯定是读线程,相反,阻塞的肯定是读线程,唤醒的肯定是写线程,那么假设只有一个Condition会有什么效果呢,缓存队列中已经存满,这个Lock不知道唤醒的是读线程还是写线程了,如果唤醒的是读线程,皆大欢喜,如果唤醒的是写线程,那么线程刚被唤醒,又被阻塞了,这时又去唤醒,这样就浪费了很多时间!

来源:https://www.iteye.com/blog/cuisuqiang-2019251

标签:Java,Condition,条件
0
投稿

猜你喜欢

  • Android的支付密码输入框实现浅析

    2022-08-19 13:57:43
  • 举例讲解Java中synchronized关键字的用法

    2023-07-01 22:20:19
  • JavaSE的逻辑控制你了解吗

    2023-01-07 01:32:22
  • Android自定义View实现圆弧进度效果

    2021-08-20 02:26:21
  • C#特性 扩展方法

    2023-01-15 03:45:15
  • C#实现FTP上传文件的方法

    2021-11-13 10:46:56
  • java开发实现五子棋游戏

    2021-09-07 12:41:32
  • RxJava+Retrofit+Mvp实现购物车

    2022-03-22 16:24:48
  • 图解红黑树及Java进行红黑二叉树遍历的方法

    2023-04-20 22:09:14
  • java中treemap和treeset实现红黑树

    2021-12-05 07:22:29
  • C#静态构造函数用法实例分析

    2022-03-18 10:32:34
  • java开发分布式服务框架Dubbo原理机制详解

    2023-01-04 19:53:01
  • JavaSE的类和对象你真的了解吗

    2021-09-17 21:14:59
  • Java中BorderLayout布局管理器的两种排列方式

    2022-03-14 08:04:35
  • C# Assembly.Load案例详解

    2021-11-06 03:20:33
  • IDEA实现JDBC的操作步骤

    2021-08-29 11:08:55
  • Java Base64解码错误及解决方法

    2023-02-09 03:36:35
  • C#记一次http协议multipart/form-data的boundary问题

    2021-07-01 17:45:49
  • java基础之String知识总结

    2022-09-24 16:25:20
  • android开发教程之自定义控件checkbox的样式示例

    2023-10-23 13:33:55
  • asp之家 软件编程 m.aspxhome.com