代码如下(举例,逻辑太多)
//实例ExecutorService 对象
public static ExecutorService es = Executors.newFixedThreadPool(5);//为每个线程均分数据进行业务逻辑
for (int i = 0; i < 5; i++) {
pageSize = perThreadTotal < pageSize ? perThreadTotal : pageSize;

if (i != countThread - 1) {
 es.submit(new DNSSoftwareThread(perThreadTotal, pageSize,
(i * perThreadTotal) + startWith, (i + 1), false));
} else {
es.submit(new DNSSoftwareThread(lastThreadTotal, pageSize,
(i * perThreadTotal) + startWith, (i + 1), true));
}
}//DNSSoftwareThread的run方法
//比如分配100条数据
for(int i=startWith;i<100;i+=pageSize){
      //每次从数据库取固定条数来跑业务
      someObj.execure(i,pageSize);
}
我的log中打出了每一个线程在执行每条数据的log,有3个现成执行完了,两个现成没执行完,但是现在不动了,java 进程还活着,但是占用CPU,Memory都是0. 不知道怎么回事。请问从哪里着手查原因。非常感谢。

解决方案 »

  1.   

    楼主:启动JConsole,查看下另外两个是否被阻塞了。
      

  2.   

    为每个线程均分数据进行业务逻辑这个想法,不太讲究。
    如果要每个线程均分,那么,自己手动编写5个线程,完成任务就可以了。
    没必要使用线程池。使用线程池,就是想尽可能充分的利用里面的空闲线程进行任务处理,
    谁闲着就用谁,而任务的处理时间和进展并不一定是相同的。所以,提交给线程池的任务,(那个DNSSoftwareThread的run方法里面,
    就没有必要使用循环了,直接 //每次从数据库取固定条数来跑业务
          someObj.execure(i,pageSize);就行。
    也就是说,每次给线程池提交的业务数据就是pageSize条,至于分配到哪个线程,
    由线程池按照自己的策略来决定。
    这样就可以化简编程的复杂度了。没有了为每个线程均分数据进行业务逻辑的代码,我想,可以避免很多问题。
    由于,楼主给出的代码,并不完整,所以,目前无法判断任务僵死在哪里。
    楼主可以尝试一下,我说的那个思路,去掉为每个线程均分数据进行业务逻辑的代码。
      

  3.   


    您好 yu2002fu 我的程序是在服务器命令行下运行的,不知道这个JConsole能不能用?
      

  4.   


    感谢 preferme 的热心回复,run方法如下://其实这里就是又一次做了分页,比如分给这个线程1万条数据,然后每次从数据库取多少的简单分页。
    @Override
    public void run() {
    DNSSoftwareService dd = new DNSSoftwareService();
    String currName = Thread.currentThread().getName();
    int p = 0;//in fact pagesize

    for (int i = STARTWITH; i < this.TOTAL; i += PAGESIZE) {
    if((i + PAGESIZE) > this.TOTAL){
    p = this.TOTAL - i;
    }else{
    p = this.PAGESIZE;
    }
    Utils.outputWithDate("Pagination query=====> : "+currName+"****************************limit "+i+","+p);
    dd.execute(i, p);
    }
    Utils.outputWithDate(currName+" has finished");
    }//至于execute这个方法 是真正的业务逻辑参数就是 limit i,p 这样从数据库每次取的数据量。之所以作这个分页是开多个线程每个线程数据量较大的话,一次性加载到内存,增加服务器负担。//execute中设计到,DB查询,外网数据请求,返回数据的分析 组织 过滤,然后存入DB,这样一条数据的业务逻辑完成。不知道是否有设计不妥之处,多谢指点。
      

  5.   

    还有就是,据说有个守护线程可以监控其他运行监控状态,网上找了好多,也没看太明白如何应用到程序里去监控,都是简单说了一下setDaemon(true)就完了。还望指点。多谢。
      

  6.   

    我从本地跑和服务器同样的情况,用jConsole监控,目前启动有时候一下子就等待状态过不去了,现在过去了,运行中,不知道会发生什么,不知道这个结果怎么看,线程1的目前信息:
      

  7.   

    没看代码,看这情况,内部是线程阻塞在某个lock对象上了 ConditionObject
      

  8.   


    都不知道ConditionObject是啥啊,也没调用过
      

  9.   

    public void run() {
            DNSSoftwareService dd = new DNSSoftwareService();
            String currName = Thread.currentThread().getName();
            int p = 0;//in fact pagesize
            
            for (int i = STARTWITH; i < this.TOTAL; i += PAGESIZE) {
                if((i + PAGESIZE) > this.TOTAL){    
                    p = this.TOTAL - i;
                }else{
                    p = this.PAGESIZE;
                }
                Utils.outputWithDate("Pagination query=====> : "+currName+"****************************limit "+i+","+p);
                dd.execute(i, p);
            }
            Utils.outputWithDate(currName+" has finished");
        }估计是里面的线程没跑完吧,把外面的线程起2个或3分别试试,能不能跑完
      

  10.   

    ExecutorService newFixedThreadPool()返回的ThreadPoolExecutor对象里面有getActiveCount(),getCompletedTaskCount()这样的方法来查看线程池状况。