机器学习和生物信息学实验室联盟

标题: 关于Java6 杀死线程问题 [打印本页]

作者: chenwq    时间: 2012-4-22 23:41
标题: 关于Java6 杀死线程问题
本帖最后由 chenwq 于 2012-4-23 14:11 编辑

问题描述:
针对,D3C串行执行分类器训练模型的改进,
提出了多线程化分类器训练过程方案。

[attach]646[/attach]
如图,首先,在主线程Main函数中,开启多个线程用于各个分类器训练(D3C的Test包含20个分类器),以及一个
线程监听程序,每隔固定时间,监测每个分类器是否训练完成,此外还用于分类器训练时间超过D3C设定的
训练时间时,移除该超时分类器线程。
全部分类器训练结束后者被移除之后,主线程被唤醒,继续执行D3C的后续操作。

分类器训练超时,杀死进程的实现:
对超时的分类器训练线程,采用interrupt()方法,将其中断。

  1. long t2 = System.currentTimeMillis();
  2. Calendar c = Calendar.getInstance();
  3. c.setTimeInMillis(t2 - startTime);
  4. if (c.get(Calendar.SECOND) >= terminateTime) {
  5.         Logger.info(InitClassifiers.classifiersName[array.get(i).getI()] + " is removed!");
  6. //         array.get(i).stop();
  7. //              array.set(i, null);
  8.          array.get(i).interrupt();
  9.                 array.remove(i);// 将已经完成的线程对象从队列中移除
  10. }
复制代码
之后,对应分类器线程的run()方法里面,检查,该线程是否被中断,
如果中断,则对其分类结果(以ArrayList保存)重新赋值,50%正确分类,50%分类失败

  1.         public void run() {

  2.                 SelectiveEnsemble se = new SelectiveEnsemble();
  3.                
  4.                 this.list[[this.i] = se.CrossValidationModel(input, classifier, numfolds,
  5.                                 correctRateArray, random, this.i, this.qqs);
  6.                 if(Thread.interrupted()){
  7.                         System.out.println("-----------------------------------------------------");
  8.                         List<Integer> tmpLst = new ArrayList<Integer>();
  9.                        
  10. //                        for(int iii = 0; iii < this.list[this.i].size(); iii++){
  11. //                                if(iii % 2 == 0)
  12. //                                        tmpLst.add(1);
  13. //                                else
  14. //                                        tmpLst.add(0);
  15. //                        }
  16.                         this.list[this.i] = tmpLst;
  17.                         this.isFinished = true;
  18.                 }
  19.                 for (int j = 0; j < this.list[this.i].size(); j++) {
  20.                         if (this.list[this.i].get(j) == 0) {
  21.                                 this.classifyErrorNo[this.i].add(j);
  22.                         }
  23.                 }
  24.                 this.isFinished = true;
  25.                 executeTime = System.currentTimeMillis();
  26.         }
复制代码
因为Java里面的参数以引用的方式传递,如果,不对上述分类器的分类结果进行重新赋值,存在着部分分类结果存入ArrayList,即上述代码中的this.list[this.i],
而部分没有存入,或者,甚至,整个结果都在被中断的过程中被清除,这样分类的结果在后续的聚类、差异性度量中将无法引用,
导致程序异常。

如果能把被移除的分类器的输出结果的重新赋值过程去掉,整个逻辑将更加清楚,代码也将不带臭味。
如果有好的办法,请大家踊跃提啊!


参考:
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
How to Stop a Thread or a Task[




欢迎光临 机器学习和生物信息学实验室联盟 (http://123.57.240.48/) Powered by Discuz! X3.2