1.stop()与destory()函数

线程是“一种运行中的代码或者函数”。既然是运行中就会涉及到是一个问题,在运行中的线程是否可以强制结束/关闭?

答案是肯定不可以的。在Java中,stop()和destory()之类的函数是官方明确不建议使用的。原因是如果强制杀死线程,那么线程执行所占用的资源,eg:文件描述符、网络连接不能正常关闭。

因此,一个线程一旦运行,就不要强制去打断,合理的关闭办法是让它自然运行完(函数执行结束),干净的释放掉所有资源,然后退出。如果是一个不断循环的运行的线程,就需要用到线程的通讯机制,让主线程通知它退出。

2.守护线程

在下面代码中:在main()函数中开启一个线程,不断的循环打印。请问:当main()函数退出之后,线程是否会被强制退出?整个进程是否会强制退出?

public static void main(String[] args){
  System.out.println("main start...");
  Thread thread1 = new Thread(()->{
    while(true){
      try{
        System.out.println("thread1 executing..");
      }catch(InterruptedExcetpion ex){
        
      }
    }
  });
  thread1.start();
  System.out.println("main end...");
}

答案是不会。在C语言中,main()函数退出后,整个程序就退出了,但在Java中并非如此。

对于如上程序,在thread1.start()前面加一行代码:thread1.setDeamon(true)。当main()函数执行结束后,线程thread1就会退出,整个进程也会退出。

当在JVM进程里面开启多个线程时,这些线程被分为两类:守护线程与非守护线程。默认开启的是非守护线程。在Java中规定:当所有非守护线程退出后,整个JVM进程就会退出。意思就是守护线程不影响整个JVM退出。eg:垃圾回收线程就是守护线程,他们在后台默默工作,当开发者的所有前台线程(非守护线程)都退出之后,整个JVM进程就退出了。

3.设置关闭的标志位

在上面代码中,线程是一个死循环。但在实际工作中,开发人员通常不会这么写,而是通过标志位来实现。如下所示:

class MyThread extends Thread{
  private boolean stopped = false;
  
  public void run(){
    while(!stopped){
      ...
    }
  }
  
  public void stop(){
    this.stopped = true;
  }
}

public static void main(String[] args){
  MyThread t = new MyThread();
  t.start();
  // 通知线程t关闭
  t.stop();
  // 等待线程t退出while循环,自行退出
  t.join();
}

上面的代码有一个问题:如过MyThread t在循环中阻塞在某个地方了,例如里面调用了object.wait()函数,那它可能永远没有机会再执行while(!stopped)的代码了,也就一直无法退出循环。

此时就要用到如下所讲的(Post not found: Java并发实现原理-多线程基础-InterruptedException函数与interrupt函数-2 Java并发实现原理-多线程基础-InterruptedException函数与interrupt函数-2).