Java并发编程-线程基础( 五 )

3.2.2 通过 stop 来终止线程

  • 我们通过查看 Thread 类或者 JDK API 可以看到关于线程的停止提供了 stop() , supend() , resume() 等方法 , 但是我们可以看到这些方法都被标记了 @Deprecated 也就是过时的 ,
  • 虽然这几个方法都可以用来停止一个正在运行的线程 , 但是这些方法都是不安全的 , 都已经被抛弃使用 , 所以在我们开发中我们要避免使用这些方法 , 关于这些方法为什么被抛弃以及导致的问题 JDK 文档中较为详细的描述 《Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?》
  • 在其中有这样的描述:

Java并发编程-线程基础文章插图
  • 总的来说就是: 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作 , 包括在 catch 或 finally 等语句中的内容 , 并抛出 ThreadDeath 异常(通常情况下此异常不需要显示的捕获) , 因此可能会导致一些工作的得不到完成 , 如文件 , 数据库等的关闭 。调用 stop() 方法会立即释放该线程所持有的所有的锁 , 导致数据得不到同步 , 出现数据不一致的问题 。
3.2.3 通过 interrupt 来终止线程
  • 通过上面阐述 , 我们知道了使用 stop 方法是不推荐的 , 那么我们用什么来更好的停止线程 , 这里就引出了 interrupt 方法 , 我们通过调用 interrupt 来中断线程
  • 当其他线程通过调用当前线程的 interrupt 方法 , 表示向当前线程打个招呼 , 告诉他可以中断线程的执行了 , 至于什么时候中断 , 取决于当前线程自己
  • 线程通过检查自身是否被中断来进行相应 , 可以通过 isInterrupted() 来判断是否被中断 。
我们来看下面代码:
public static void main(String[] args) {//创建 interrupt-1 线程Thread thread = new Thread(() -> {while (true) {//判断当前线程是否中断 ,if (Thread.currentThread().isInterrupted()) {System.out.println("线程1 接收到中断信息 , 中断线程...");break;}System.out.println(Thread.currentThread().getName() + "线程正在执行...");}}, "interrupt-1");//启动线程 1thread.start();//创建 interrupt-2 线程new Thread(() -> {int i = 0;while (i <20){System.out.println(Thread.currentThread().getName()+"线程正在执行...");if (i == 8){System.out.println("设置线程中断....");//通知线程1 设置中断通知thread.interrupt();}i ++;try {TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}},"interrupt-2").start();}打印结果如下:
Java并发编程-线程基础文章插图
上述代码中我们可以看到 , 我们创建了 interrupt-1 线程 , 其中用 interrupt 来判断当前线程是否处于中断状态 , 如果处于中断状态那么就自然结束线程 , 这里的结束的具体操作由我们开发者来决定 。 再创建 interrupt-2 线程 , 代码相对简单不阐述 , 当执行到某时刻时将线程 interrupt-1 设置为中断状态 , 也就是通知 interrupt-1 线程 。
线程中断标记复位 :
在上述 interrupt-1 代码中如果加入 sleep 方法 , 那么我们会发现程序报出 InterruptedException 错误 , 同时 , 线程 interrupt-1 也不会停止 , 这里就是因为中断标记被复位了, 下面我们来介绍一下关于中断标记复位相关的内容