为什么ExecutorService.shutdownNow方法无法阻止线程

max*_*shi 5 java

package util.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ShutdownDemo {
 public static void main(String[] args) throws InterruptedException{
  ExecutorService executor = Executors.newSingleThreadExecutor();

  executor.execute(new Runnable(){

   @Override
   public void run() {
    while(true){
     System.out.println("-- test --");
    }
   }

  });

  TimeUnit.SECONDS.sleep(3);

  executor.shutdownNow();
 }
}
Run Code Online (Sandbox Code Playgroud)

我已经调用了shutdownNow方法,为什么控制台继续打印" - test - "??

chu*_*ubs 10

查看JavaDoc中的Thread.stop(),原因如下:

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop()

基本上,您的线程必须自行停止,以使您的程序保持安全.只是停止一个线程会使程序处于不可预测的状态,在这种状态下,线程拥有的锁不会被释放,资源也不会返回给操作系统.最终使程序对死锁,内存泄漏无法释放,并可能影响操作系统的稳定性.如果您使用C语言或任何其他语言,这实际上没有任何不同,因为停止本机线程存在这些问题.记住线程不是与其他线程共享内存和状态的进程,因此它们必须表现和合作.

Java用于中断线程而不是杀死线程,因此线程在编写时必须符合此模型.因此,虽然(真实)在你的程序中是不好的做法.相反,您需要查看您的线程是否已被中断,并自行关闭.使用Thread.sleep并正确处理InterruptedException.或者在while循环中检查Thread.isInterrupted().


Col*_*lin 1

JavaDocs来看,ExecutorService#shutdownNow 方法不能保证实际停止正在执行的作业。最好改变一些状态变量,长时间运行的作业将定期检查这些状态变量,并在检测到更改时退出其运行循环。