【问题标题】:How can I make sure that all threads ended before the main thread ends?如何确保所有线程在主线程结束之前结束?
【发布时间】:2012-07-13 10:39:42
【问题描述】:

我有以下一段代码来使用 java 多线程。

    ExecutorService threadExecutor = Executors.newFixedThreadPool(10);

    while(resultSet.next()) 
       { 
          name=resultSet.getString("hName");
          MyRunnable worker = new  Myrunnable(name);
          threadExecutor.execute( worker );
          Counter++;
    }


 threadExecutor.shutdown();
 System.out.println("thread shutdown");

 // Wait until all threads are finish
 while (! threadExecutor.isTerminated()) {

 }

 System.out.println("Finished all threads");

}// end try
    catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println("END MAIN");

    DBConnection.con.close();           

和run函数如下:

//The constructor
MyRunnable (String name)  {
        this.name=name;
    }

public void run() 
{
        myclass Obj=new myclass();
        try {
            Obj.myFunction(name);
        } catch (Exception e) {

            System.out.println("Got an Exception: "+e.getMessage());
        }
        System.out.println(" thread exiting.");
}

在之前的帖子中,有人建议使用以下代码等待线程结束。

while (! threadExecutor.isTerminated()) {
   try {
       threadExecutor.awaitTermination(1, TimeUnit.SECOND);
   }
   catch (InterruptedException e) {
        // you have to determine if someone can interrupt your wait
        // for the full termination of the executor, but most likely,
        // you'll do nothing here and swallow the exception, or rethrow
        // it in a RuntimeException
   }
}

现在,我在这两种情况下都面临问题。如果我使用第一种方法,我的程序会运行,但最后它会进入一个无限循环,然后所有线程都退出。 END MAIN 打印输出永远不会出现。如果我使用第二种方法,从运行程序开始出现以下错误,并且END MAIN打印输出永远不会出现:

遇到异常:连接关闭后不允许进行任何操作。 线程退出。

请以正确的方式告诉我,让我的主线程在我的所有子线程退出后退出。

【问题讨论】:

  • while 循环可能会使调度程序处于饥饿状态,请尝试将 Thread.sleep(250) 或 Theead.yield 放入其中
  • 在哪里放置 Thread.sleep(250) 或 Theead.yield ?由于我是处理多线程的新手,请您进一步澄清一下。
  • 对不起,在你用来等待另一个线程完成的while循环中
  • @Jury A:你确定你所有的任务都正常终止了吗?
  • 通过在单线程中测试代码,一切正常终止。

标签: java multithreading


【解决方案1】:

首先,为什么要忙着旋转?最节省 CPU 的方法就是放一个很长的awaitTermination

threadExecutor.shutdown();
threadExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

至于池没有终止的原因,很可能是因为你的线程任务没有正常终止。

【讨论】:

  • 但我不希望我的程序运行几天。我需要它在线程完成工作后立即结束。当我尝试使用相同数量的线程以减少名称数量的相同程序时(我从数据库中读取名称,如代码所示),例如,对于 6 个名称,程序完美地开始和结束。但是当我读到 2000 个名字时,最后的线程并没有结束。它永远存在。另外, System.out.println("thread shutdown");永远不要打印出来。
  • @JuryA 上面的建议将阻塞,直到所有线程都完成后再返回。这是一项改进,因为您在大超时时等待一次,而不是在小超时时等待多次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多