概述
ScriptEngine是线程安全的,自身没有线程问题,但是变量作用域(Bindings)存在线程问题。一般计算时,如果不考虑线程,都是使用的默认Bindings:
通过源码可以看到,如果不指定Bindings,默认使用内置的Bindings。
这就会导致多线程存在问题,一个线程的变量可能会被另一个线程覆盖掉,导致计算结果出错。所有为了保证不同线程变量作用域相互独立,可以根据线程号来创建Bindings:
/**
* 得到当前线程号
*/
public int getCurrentThread(){
String threadName = Thread.currentThread().getName().replace("Thread-","");
return NumberUtil.saveToInteger(threadName,1);
}
private Map<Integer,Bindings> bindingMap = new HashMap<>(50);
首先定义一个全局map,用来保存线程号和Bindings作用域的映射,可以不用每次计算都去创建新的Bindings,使同一个线程多次计算时,只创建一次Bindings。
/**
* 根据线程号返回binding,不存在时创建
* @param threadNum 线程号
*/
public Bindings getEngineBinding(int threadNum){
return bindingMap.computeIfAbsent(threadNum, k -> engine.createBindings());
}
该线程用完脚本引擎后,必须手动移除Bindings,否则不久就可能导致内存溢出。
一般建议将cleanEngineScope()放在finally语句块中执行,保证异常也一定会执行
/**
* 根据线程号清除Binding
* @param threadNum 线程号
*/
public void cleanEngineScope(int threadNum){
bindingMap.remove(threadNum);
}
完整代码:http://download.csdn.net/download/qq_36635569/12077855
最后
以上就是妩媚洋葱为你收集整理的java脚本引擎Groovy并发控制的全部内容,希望文章能够帮你解决java脚本引擎Groovy并发控制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复