多线程查询的时候Model中的getSqlPara方法中解析sql的时候存在并发问题

java.lang.NullPointerException
at java.lang.String.<init>(String.java:505) ~[?:1.7.0_71]
at com.jfinal.template.stat.ast.Text.getChars(Text.java:83) ~[jfinal-3.3.jar:?]
at com.jfinal.template.io.CharWriter.write(CharWriter.java:85) ~[jfinal-3.3.jar:?]
at com.jfinal.template.stat.ast.Text.exec(Text.java:49) ~[jfinal-3.3.jar:?]
at com.jfinal.template.stat.ast.StatList.exec(StatList.java:68) ~[jfinal-3.3.jar:?]
at com.jfinal.template.Template.render(Template.java:75) ~[jfinal-3.3.jar:?]
at com.jfinal.template.Template.renderToString(Template.java:95) ~[jfinal-3.3.jar:?]
at com.jfinal.plugin.activerecord.sql.SqlKit.getSqlPara(SqlKit.java:167) ~[jfinal-3.3.jar:?]
at com.jfinal.plugin.activerecord.Model.getSqlPara(Model.java:965) ~[jfinal-3.3.jar:?]

评论区

JFinal

2018-04-02 14:17

虽然这个概率极低,而且即便是碰到也只会发生一次,但确实会有这个问题

jfinal 3.4 已经改进了这里,用上 jfinal 3.4 的方法参考这个贴子:
http://www.jfinal.com/share/714

记得一定要给我反馈,要确保这个问题解决掉,追求完美

感谢你的反馈

ygh331

2018-04-02 15:23

我刚更新3.4的代码测试了,private byte[] bytes;
private char[] chars; 这两个变量时全局变量,按照目前这种方式修改还是又问题的,而且出问题的频率比之前还高,我只用2个线程就有问题

JFinal

2018-04-02 15:40

代码贴出来看看,改进后的还出问题就很奇怪了

ygh331

2018-04-02 15:59

这是异常:
java.lang.NullPointerException
at java.lang.String.(String.java:515)
at com.jfinal.template.stat.ast.Text.getChars(Text.java:91)
at com.jfinal.template.io.CharWriter.write(CharWriter.java:85)
at com.jfinal.template.stat.ast.Text.exec(Text.java:49)
at com.jfinal.template.stat.ast.StatList.exec(StatList.java:68)
at com.jfinal.template.Template.render(Template.java:79)
at com.jfinal.template.Template.renderToString(Template.java:99)
at demo.com.software.lc.JfinalSqlTest$1.run(JfinalSqlTest.java:41)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
下面是模拟多线程解析sql模板
public class JfinalSqlTest {
private static Template template;
private static String sql;
static{
Engine engine = Engine.use();
// engine.addSharedMethod(new StringUtils());
engine.addSharedMethod(new EngineUtil());
engine.setBaseTemplatePath("E:\\workspace\\demo\\src\\main\\resources\\sql");
template = engine.getTemplate("test.sql");
}
public static void main(String[] args) {
final CountDownLatch count = new CountDownLatch(10000);
try {
ExecutorService threadPool = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
threadPool.execute(new Runnable() {

@Override
public void run() {
try {
Map map = new HashMap();
map.put("order_pay_type","01");
map.put("channel_id",",WKLC,");
map.put("start_time","2017-12-29 17:58:03");
sql = template.renderToString(map);
// SqlPara sqlPara = SqlUtil.INSTANCE.getSqlPara(sql, map);
// System.out.println("正常解析");
} catch (Exception e) {
e.printStackTrace();
} finally{
count.countDown();
}
}
});
}
threadPool.shutdown();
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(count.await(120, TimeUnit.MINUTES)){
System.out.println("处理完成!");
};
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

JFinal

2018-04-02 16:12

@ygh331 又加了个 if 判断,再试一下,记得给我反馈

记得要先删除本地 maven 库中的 jfinal 3.4-SNAPSHOT 版本,重新 mvn install

ygh331

2018-04-02 17:08

这么处理就没问题了,多谢

JFinal

2018-04-02 17:10

@ygh331 感谢你的反馈

JFinal

2018-04-02 19:27

@ygh331 这部分代码又重构了一下,更加简洁优雅,试用后多给反馈

热门反馈

扫码入社