系统执行阻塞分析及解决方案

1.  背景

系统上线后,准备通过logQuery进行计算,并检验数据是否准确,但程序计算1w左右时停止。

2.  分析

系统运行原理

系统通过logQuery系统执行Runtime方法调用shell脚本启动java补货计算系统。

问题分析

         在系统死锁时,通过jstack观察jvm中所有线程运行情况和线程状态。


发现有一个线程处于runnable状态并locked了log4j的callAppenders方法和doAppend方法,由于callAppenders和doAppend中含有synchronized,所以导致其他线程死锁。



         继续进行测试及分析,发现直接运行shell脚本进行补货计算没有发生死锁问题,所以可以排除shell脚步及计算程序问题。

         于是将问题集中到logQuery代码中,通过大量的测试及百度搜索,最终将问题缩小到Runtime方法的Process返回类型中。

查看JAVA API:

大喜,问题估计找到了。

系统死锁时代码结构

串行运行,需要 errorBr流全部输出完毕后,才会输出br流程中信息。可能会导致API中所描述的死锁。

随即写了一个多线程进行测试。

注意:代码后需要添加process.waitFor(),作用就是当前线程等待,直到所有子线程运行完毕。

至此补货系统线程阻塞问题解决。

3.  关于Ant对Runntime方法的使用

下载ant-source-1.7.1,导入到eclipse中。

进入org.apache.tools.ant.taskdefs.Exec.java中,查看protectedint run(String command) 方法。

窃喜,跟当初解决方案一样,都是多线程输出getInputStream和getErrorStream两个InputStream流。

不过值得注意的是:ant中使用了join及destroy,使代码更加完善。

 

Exec.java在ant1.2之后已经废弃不在维护,取而代之的是org.apache.tools.ant.taskdefs.Execute.java,Execute加强了对代码的抽象性和扩展性,但对于本次分析,使用Exec.java更直观易懂。

发布了22 篇原创文章 · 获赞 10 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章