1

我有如下代码:

new Thread(new Test1Runnable()).start();     // Line (a)

public class Test1Runnable implements Runnable {  

    public void run() {
       Test2Runnable task1 = new Test2Runnable();
       ExecutorService executor = Executors.newSingleThreadExecutor();

          try {
              executor.submit(task1);

              while(true) {
                  if(task1.isDone()) {
                      break;
                  }
                  // Thread.sleep(2000);   // Line (b)
              }

              if(!task1.hasError()) {   // Line (c)
                  executor.submit(new Test3Runnable());
              }
          } catch(Exception ex) {
              if(executor != null) {
                  executor.shutdown();
              }
          }
    }
}

public class Test2Runnable implements Runnable {

    private Exception error;
    private boolean done;

    public void run() {
        reset();        
        doRun();
        done = true; 
    }

    protected void doRun() {
        try{
           // ...
           // ....
        } catch(Exception ex) {

        }
    }

    private void reset() {
         error = null;
         done = false;        
    }   

    public boolean isDone() {
        return done;
    }

    public boolean hasError() {
       return getError() != null || getNonSuccess() > 0;
    }

    public Exception getError() {
       return error;
    }

}

当我在 (a) 行运行 Test1Runnable 并注释行 (b) 时出现问题,然后线程挂起而不运行到 (c) 行。如果我取消注释 (b) 行或在 (c) 行添加断点并激活远程调试,线程将继续正常运行到最后。任何人都可以给我一些建议吗?为什么线程不能继续运行?所有线程无一例外地运行。

4

1 回答 1

1

看起来你在这里有一个竞争条件,所以执行结果取决于时间、调试启用等。发布的代码或多或少都很好,错误很可能在 Test2Runnable 类中。我想有些标志(isDone、hasError)存在可见性问题。尝试将它们声明为 volatile。请在此处添加 Test2Runnable 代码,我将能够给出更准确的答案。

于 2013-06-05T04:53:59.517 回答