Condition条件组件简介、源码、相关样例

what任意一个Java对象,都拥有一组监视器方法,这些方法定义在java.lang.Object上,主要包括wait()、wait(long timeout)、notify()、notifyAll()方法,这些方法与synzhronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,wherewhyConditon相对于Object Monitor来说,功能更加全面一些。我们可以来看下对比:对比
摘要由CSDN通过智能技术生成

what

任意一个Java对象,都拥有一组监视器方法,这些方法定义在java.lang.Object上,主要包括wait()、wait(long timeout)、notify()、notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,

where

Condition接口的实现类ConditionObject是同步器AQS的内部类,因为Condition的操作需要获取相关联的锁,所以作为同步器的内部类也比较合理。

why

Conditon相对于Object Monitor来说,功能更加全面一些。我们可以来看下对比:

对比项 Object Monitor Methods Condition
前置条件 获取到对象的锁 调用Lock.lock()方法获取锁,然后调用Lock.newCondition()方法新建Condition对象
调用方式 通过object对象调用或者直接调用:object.wait()或者直接wait() 通过condition对象调用:condition.await()
等待队列个数 一个 一个condition对象对应一个等待队列,condition对象可重复新建
当前线程释放锁并进入等待状态 支持,wait() 支持,await()
当前线程释放锁并进入等待状态,在等待状态中不响应中断 不支持 支持,awaitUninterruptibly()
当前线程释放锁并进入超时等待状态 支持,wait(long timeout) 支持,awaitNanos(long nanosTimeout)
当前线程释放锁并进入等待状态到将来的某个时间 不支持 支持,awaitUntil(Date deadline)
唤醒等待队列中的一个线程 支持,notify(),唤醒哪个线程需要看操作系统对多线程管理的实现 支持,signal(),唤醒等待队列中的首节点
唤醒等待队列中的全部线程 支持,notifyAll() 支持,signalAll()

API

condition的主要入口方法以及描述

方法名称 描述
void await() throws InterruptedException 当前线程进入等待状态直到被通知或者中断
当前线程将进入运行状态并从await()方法返回的情况有两种:
1.其他线程调用该Condition的signal()或者signalAll()方法,而当前线程被选中唤醒
2.其他线程通过调用interrupt()方法中断当前线程
如果当前等待线程从await()方法返回,那么表明该线程已经获取到了Condition对象所对应的锁
void awaitUninterruptibly() 当前线程进入等待状态直到被通知,从方法名称上可以看出该方法对中断不敏感
long awaitNanos(long nanosTimeout) throws InterruptedException 当前线程进入等待状态直到被通知、中断或者超时。返回值表示剩余的时间,如果在nanosTimeout纳秒之前被唤醒,那么返回值就是nanosTimeout - 实际耗时,如果返回值是0或者负数,那么可以认定是超时了
boolean awaitUntil(Date dateline) throws InterruptedException 当前线程进入等待状态直到被通知、中断或者到某个时间。如果没有到指定时间就被通知,方法返回true,否则,表示到了指定时间,方法返回false
void signal() 唤醒当前condition对象等待队列中的首节点,该线程从等待方法返回前必须获得与Condition相关联的锁
void signalAll() 唤醒当前condition对象等待队列中的所有节点,能够从等待方法返回的线程必须获得与Condition相关联的锁

源码

1.等待队列

每个Condition对象都包含着一个队列,我们称之为等待队列,该

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flowable 是一个流程引擎框架,条件判断是其中非常重要的一部分。Flowable 中的条件判断主要分为两类:表达式条件判断和脚本条件判断。下面分别介绍这两种条件判断的源码实现。 1. 表达式条件判断 表达式条件判断是通过表达式来判断条件是否成立。Flowable 中支持的表达式语言有 EL 表达式、Juel 表达式、Mvel 表达式等。这里以 EL 表达式为例。 首先我们看到 Flowable 中的表达式条件判断是通过 org.flowable.bpmn.model.SequenceFlow 类中的 conditionExpression 属性来实现的。该属性的类型为 String,表示一个表达式字符串。 在执行条件判断时,Flowable 会将这个表达式字符串解析成一个 EL 表达式对象,并将当前执行上下文中的变量传递给该表达式对象进行计算,最终得出判断结果。下面是相关源码实现: ```java public class SequenceFlow extends FlowElement { protected String conditionExpression; // ... public boolean hasCondition() { return StringUtils.isNotEmpty(conditionExpression); } public Expression getConditionExpression() { if (hasCondition()) { ExpressionManager expressionManager = Context.getProcessEngineConfiguration().getExpressionManager(); return expressionManager.createExpression(conditionExpression); } return null; } // ... } ``` 可以看到,当 conditionExpression 属性不为空时,调用 getConditionExpression 方法会将该属性解析成一个 EL 表达式对象返回。 接下来看一下条件判断的执行过程。在 Flowable 中,条件判断是通过 org.flowable.engine.impl.bpmn.behavior.ConditionalEventBehavior 类的 execute 方法实现的。该方法中会先获取 SequenceFlow 对象的 conditionExpression 属性,然后调用 getConditionExpression 方法解析成一个 EL 表达式对象。最后将当前执行上下文中的变量传递给该表达式对象进行计算,得出判断结果。下面是相关源码实现: ```java public class ConditionalEventBehavior extends FlowNodeActivityBehavior { // ... @Override public void execute(ActivityExecution execution) throws Exception { // ... SequenceFlow outgoingSequenceFlow = (SequenceFlow) conditionalEvent.getOutgoingFlows().get(0); if (outgoingSequenceFlow.hasCondition()) { Expression conditionExpression = outgoingSequenceFlow.getConditionExpression(); Object value = conditionExpression.getValue(execution); if (value instanceof Boolean && (Boolean) value) { leave(execution); } } else { leave(execution); } // ... } // ... } ``` 可以看到,当 SequenceFlow 对象的 conditionExpression 属性不为空时,会调用 getConditionExpression 方法获取一个 EL 表达式对象,并将当前执行上下文中的变量传递给该表达式对象进行计算。最终得出的判断结果为 true 时,会继续执行下一步任务,否则不会执行。 2. 脚本条件判断 脚本条件判断是通过脚本来判断条件是否成立。Flowable 中支持的脚本语言有 Groovy、JavaScript、Python 等。这里以 Groovy 为例。 在 Flowable 中,脚本条件判断是通过 org.flowable.bpmn.model.ScriptTask 类中的 script 属性来实现的。该属性的类型为 String,表示一个 Groovy 脚本字符串。 执行脚本条件判断的过程与表达式条件判断类似,在这里不再赘述。需要注意的是,在使用脚本条件判断时,需要在流程引擎配置中添加对应的脚本引擎。下面是相关源码实现: ```java public class ScriptTask extends TaskWithFieldExtensions { protected String scriptFormat; protected String script; // ... public boolean hasScript() { return StringUtils.isNotEmpty(script); } public Object executeScript(VariableScope variableScope) { ScriptingEngines scriptingEngines = Context.getProcessEngineConfiguration().getScriptingEngines(); ScriptEngine scriptEngine = scriptingEngines.getScriptEngine(scriptFormat); return scriptingEngines.evaluate(script, scriptEngine, variableScope); } // ... } ``` 可以看到,当 script 属性不为空时,调用 executeScript 方法会将该属性解析成一个 Groovy 脚本对象,并将当前执行上下文中的变量传递给该脚本对象进行计算,最终得出判断结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值