首页 > 编程语言 >Java-interrupt方法的一个小的注意点

Java-interrupt方法的一个小的注意点

时间:2022-12-09 15:45:49浏览次数:56  
标签:Java Thread doSomething currentThread 线程 注意 interrupt public mTaskThread

Java-interrupt方法的一个小的注意点

记录Java 中 interupt() 方法的一个小的知识点。

开发过程中,经常有需要去终止线程,终止线程的方式无外乎有两种 标志位interrupt(), 前者没什么好说的,就是定义一个bool类型的变量,只是需要注意将该变量声明成 volatile。后者的话主要用于终止带阻塞状态的线程,当然也可以用来终止不带阻塞状态的线程,这里再来复习一下:

关于终止线程的介绍,可参考:Java: Java终止线程的几种方式

终止不带阻塞状态的线程

TaskCase.java

package com.yongdaimi.dmeo;


public class TaskCase {

	private Thread mTaskThread;
	
	public void start() {
		mTaskThread = new Thread() {
			
			@Override
			public void run() {
				super.run();
				
				System.out.println(Thread.currentThread().getName()+" start running...");
				
				// 模拟重复执行的任务
				while (!Thread.currentThread().isInterrupted()) {
					System.out.println("doSomething");
				}
				
				System.out.println(Thread.currentThread().getName()+" stop running...");
				
			}
			
		};
		mTaskThread.start();
	}
	
	/**
	 * 使用此方法进行终止
	 */
	public void calcel() {
		mTaskThread.interrupt();
	}
	
	
}

Test.java

package com.yongdaimi.dmeo;

public class Test {

	public static void main(String[] args) {
		
		
		TaskCase task = new TaskCase();
		task.start();
		
		// 2s 后将测试线程终止
		try {
			Thread.currentThread().sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		task.calcel();
		
	}
	
}

运行:

doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
Thread-0 stop running...

可以看到使用此方法,2秒后是可以将执行线程正常终止的。

那如果加了阻塞状态呢?

TaskCase.java

package com.yongdaimi.dmeo;


public class TaskCase {

	private Thread mTaskThread;
	
	public void start() {
		mTaskThread = new Thread() {
			
			@Override
			public void run() {
				super.run();
				
				System.out.println(Thread.currentThread().getName()+" start running...");
				
				// 模拟重复执行的任务
				while (!Thread.currentThread().isInterrupted()) {
					System.out.println("doSomething");
					
					// 模拟阻塞 500ms
					try {
						Thread.currentThread().sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				System.out.println(Thread.currentThread().getName()+" stop running...");
				
			}
			
		};
		mTaskThread.start();
	}
	
	/**
	 * 使用此方法进行终止
	 */
	public void calcel() {
		mTaskThread.interrupt();
	}
	
	
}

这里在线程中添加一段code, 使线程临时阻塞500ms, 再次执行:

image-20221209152859986

这时发现虽然有走到异常的代码块里,但是线程仍然能够正常执行,没有退出,Why? 这是因为:

「注意:发生异常时线程的中断标志为会由true更改为false。」

所以最好这样写成这样:

// 模拟重复执行的任务
				while (!Thread.currentThread().isInterrupted()) {
					System.out.println("doSomething");
					
					// 模拟阻塞 500ms
					try {
						Thread.currentThread().sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
						// 重置中断标志位为true
	                    Thread.currentThread().interrupt();
					}
				}

在出现异常后,重置中断标志位,这样再次执行后,就可以顺利中断线程了:

image-20221209153306915

当然也可以在出现异常时,直接使用return语句终止,那样也是可以的,今天在是review一个同事的code时发现了此问题,所以记录一下。

参考链接:

为什么说volatile+interrupt是停止线程最优雅的姿势?

标签:Java,Thread,doSomething,currentThread,线程,注意,interrupt,public,mTaskThread
From: https://www.cnblogs.com/yongdaimi/p/16969091.html

相关文章

  • 【Java基础】12.9习题(封装,继承)
    水仙花数importjava.util.*;//万能头publicclassMain{publicstaticvoidmain(String[]args){for(inti=100;i<1000;i++){......
  • Java使用Steam流对数组进行排序
    原文地址:Java使用Steam流对数组进行排序-Stars-One的杂货小窝简单记下笔记,不是啥难的东西sorted()方法里传了一个比较器的接口Filefile=newFile("D:\\temp\\db_ba......
  • java概述
    1.java概述1.1java发展史​1995年,Sun发布JDK1.0。​1998年,JDK1.2,后续接连JDK1.3,1.4,1.5,更名为Java5,最新版本为OracleJDK17于2021年发布。JDK17是LTS版本,J......
  • java获取链接数据
    java获取链接数据packagecom.dongao.test;importcom.alibaba.fastjson.JSON;importcom.dongao.project.common.util.HttpPostUtil;importjava.util.*;/***@ClassName:......
  • java.io.InvalidClassException异常解决
    java.io.InvalidClassException异常解决​​1.什么是serialVersionUID​​​​2.java.io.InvalidClassException产生原因?​​​​3.java.io.InvalidClassException解决方案......
  • Java中new Long(String s)和Long.valueOf(String s)的区别
    想要知道newLong(Strings)和Long.valueOf(Strings)的区别,还是得从源码直接看比较直观newLong(Strings)Long.valueOf(Strings)从源码可以看出,使用newLong(s)和Long.v......
  • java实现文件对比
    java实现文件对比​​需求​​​​实现效果​​​​后端代码引入​​需求web项目需要实现文件内容对比功能,开发语言是java,也就是通过java实现类似于svn的文件对比功能实现效......
  • Mysql开启ssl加密协议及Java客户端配置操作指南
    Mysql开启ssl加密协议及Java客户端配置操作指南​​Mysql配置​​​​验证Mysql开启SSL​​​​Java客户端操作​​​​生成证书密码​​​​配置数据库连接​​​​工具配......
  • Java格式化日期 微秒
    Java格式化日期微秒​​Date、LocalDateTime格式化微秒值​​​​Date、LocalDateTime互转​​本文主要讲述Java日期格式化及格式化日期到微秒Date、LocalDateTime格式化......
  • Java项目开发小tips
    1、idea对于JS代码的兼容性较差,编写了js代码但是有时候不能正常加载。解决方法:(1)idea缓存清理;  (2)clear-install;先clear,清理完成之后再install。  (3)rebuild重......