A线程在使用Lock获得锁的后,可能会由于某些条件不满足,而不能继续执行,需要等待条件满足时,可以使用 Condition,Lock接口有一个newCondition()方法实化Condition,调用 Condition.await()当前线程释放锁,进入阻塞状态,当B线程获得这个锁并使条件满足时,调用同一个Condition实例的notify或notifyAll方法时,A线程被唤醒,但并未执行,需要B线程释放锁之后,A线程能够得到锁,才从await之后的代码执行。
A线程调用Condition.await()方法之后,
如果A线程在进入await方法之前被中断,await立即返回,抛出InterruptedException
,
否则进入阻塞状态,A线程被唤醒的条件:
1.同一个Condition实例的notifyAll被调用
2.同一个Condition实例的notify被调用,碰巧将A线程选为被唤醒的线程
4.有可能产生”虚假唤醒“
由于A线程可能是被”虚假唤醒“的,则此await方需在一个循环块中检测条件是否满足。
A线程被唤醒后,需要获得Lock才能执行后续程序, 未能获得LOCK则继续阻塞。
如果A线程阻塞过程中,被其它线程中断,那么唤醒并获得锁后,await方法抛出InterruptedException
,
如果A线程被唤醒之后,获得锁之前,被其它线程中断,则调用设标中断标志,Thread.currentThread().interrupt();
方法:
void |
有可能被“虚假唤醒" 需要在循环中使用 |
boolean |
有可能被“虚假唤醒" 需要在循环中使用 |
long |
|
void |
awaitUninterruptibly() 造成当前线程在接到信号之前一直处于等待状态。 |
boolean |
awaitUntil(Date deadline) 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。 |
void |
signal() 唤醒一个等待线程。 |
void |
signalAll() 唤醒所有等待线程。 |
java API中给出的示例:
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
源码分析:
await方法:
public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException();//刚进入方法时如果有中断,抛出异常 Node node = addConditionWaiter();//新生成一个等待节点 int savedState = fullyRelease(node);//释放多层锁 int interruptMode = 0; while (!isOnSyncQueue(node)) {//此节点未在同步节点队列中,isOnSyncQueue会返回假,直至signal被调用时才加入到队列中跳出循环 LockSupport.park(this);//线程阻塞,线程可能被”虚假唤醒“因此需要循环 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break;//线程被唤醒后,监测线程中断标志, 发生中断则把node存入同步节点队列 ,跳出循环 } //将节点存入同步节点队列目的是按队列顺序获得锁 if (acquireQueued(node, savedState) && interruptMode != THROW_IE)//acquireQueued方法内存是个死循环,直至获得锁才返回,未获得锁就继续阻塞 interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode);//发生中断抛出异常或设置中断标志 }
相关推荐
Run Condition Plugin 1.0 hpi
线程通信(Condition)实例,完整的代码文件,你只需要编译运行即可,就可以看看结果,然后分析。
前端项目-condition,Advanced condition library
the wind turbine in operation, implementation of condition monitoring system (CMS) and fault detection system (FDS) is paramount and for this purpose ample knowledge of these two types of systems is ...
通过@Bean和@Condition 注解自定义对于的condition里面根据自定义的条件实现指定类注入到spring中;@ConditionalOnProperty可以根据配置文件中的 属性值不同将不同的类注入到spring中 该资源中案例完整,代码简单移动
详细介绍了线程同步条件变量condition_variable的使用和它的源码,涉及到unique_lock, mutex, lock_guard, 虚假唤醒和惊群效应。
MyBatisPlus条件构造器Condition的用法示例代码
All controllers for the general control problem LMI existence condition and state space formulas
解决race condition问题,根据git最新源码编译
Condition Monitoring and Faults Diagnosis of Induction Motors Electrical Signature Analysis
通过java语言编写的生产者消费者,实现方法为lock类和condition类的配合完成。
rest_condition, Django rest框架的复杂权限流( http rest_conditiondjango-rest-framework的复杂权限流。安装安装最新版本的最简单方法是使用 pip/easy_install从PyPI中提取它:pip install rest_condit
race-condition-exploit, 帮助开发web应用程序竞争条件的工具 竞争条件利用帮助开发web应用程序竞争条件的工具用法$ python rc-exploit --helpusage: rc-exploit [-h] [--threads THREADS] plugin.. .Ra
线程并发控制condition 互斥量 多线程写的:生产者、消费者问题
SQL_CONDITION组成WHERE条件类
在jdk1.5以后,JAVA提供了Lock类来实现和synchronized一样的功能,并且还提供了Condition来显示线程间通信。 Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文章的所有...
python 条件同步的使用 条件同步:threading.Condition 多线程同步,python2例程 多线程的同步 多线程情况下最常见的问题之一:数据共享; 当多个线程都要去修改某一个共享数据的时候,需要对数据访问进行同步...
1、ReentrantLock简介 2、ReentrantLock函数列表 3、重入的实现 4、公平锁与非公平锁 5、ReentrantLock 扩展的功能 6
spring缓存中用conditon限制放入缓存的数据。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。