java运行groovy脚本并发问题及解决

8 篇文章 0 订阅
4 篇文章 1 订阅

专题导航

一、java调用groovy及groovy中如何使用springBean
二、java运行groovy脚本内存问题及解决
三、java运行groovy脚本并发问题及解决
四、java运行groovy工具类

一、问题重现

之前我们为了解决fullGC问题,使用Map缓存得到的Script对象,达到了类似单例的效果。但是当script运行需要传参时,存在如下问题:高并发下(或极短时间内有两个进程调用同一对象),第一个进程获取到script后,进行参数绑定,但还未执行逻辑代码时,第二个进程又进行参数绑定,则第一个进程则会调用第二个进程的参数

说白了就是:线程不安全

二、解决

线程安全问题,解决起来无非就是:加锁

尝试加锁:

	static Lock lock = new ReentrantLock();
    public static Object engine(String filePath, String fileName, Map<String, Object> variable) {
        Binding binding = new Binding();
        if (CollectionUtil.isNotEmpty(variable)) {
            variable.entrySet().stream().filter(entry -> StrUtil.isNotBlank(entry.getKey()) && ObjectUtil.isNotEmpty(entry.getValue()))
                    .forEach(entry -> binding.setVariable(entry.getKey(), entry.getValue()));
        }
        Object result;
        Script script = getScriptInstance(filePath, fileName);
        lock.lock();
        try {
            script.setBinding(binding);
            result = script.run();
        }finally {
            lock.unlock();
        }
        return result;
    }

并发状态下查看运行状态:
在这里插入图片描述
在这里插入图片描述

线程全部排序运行,多个脚本不存在并发情况

三、继续优化

并发问题解决了,但是多个脚本很明显不存在并发问题,参数也不会修改串联,能否继续优化,让单个对象不能同时被多个线程调用,但不同对象可以并行呢?

话不多说,上代码:

public static Object engine(String filePath, String fileName, Map<String, Object> variable) {
        Binding binding = new Binding();
        if (CollectionUtil.isNotEmpty(variable)) {
            variable.entrySet().stream().filter(entry -> StrUtil.isNotBlank(entry.getKey()) && ObjectUtil.isNotEmpty(entry.getValue()))
                    .forEach(entry -> binding.setVariable(entry.getKey(), entry.getValue()));
        }
        Object result;
        Script script = getScriptInstance(filePath, fileName);
        //对象锁,因为要赋值,所以一个对象同时只能被一个线程调用
        synchronized (script){
            script.setBinding(binding);
            result = script.run();
        }
        return result;
    }

运行结果:

t.run();
}
return result;
}


运行结果:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200914164721659.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaXFpbmJ1c2hpemhlbmc=,size_16,color_FFFFFF,t_70#pic_center)
可以看到同实例串行,不同实例并行

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值