怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?

怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?示例:查看状态:刚才我们讲过,一个线程里面任务正常执行完毕,状态就是TERMINATED,就是终止状态。但是,如果我线程里面的任务一直没有执行完成,我想去终止这个线程,或者我给点信息给到线程里,告诉线程我想终止结束呢!所以我可以强制去关闭线程:线程提供一个stop方法,该方法不建议使用,已经过时了!!因为stop是强行关闭线程,线程里面的任务都不在执行,不管线程的任务是否执行成功与否,就算执行到一半也会强制关闭!导致很多不可控制的结果,比如支付付一半等等!!所以我们要需要去优雅的关闭。什么叫做优雅关

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

怎么查看线程状态

  1. jps指令查看我当前的进程ID
  2. jstack 线程ID

示例:

public class StatusDemo { 
   
	public static void main(String[] args) { 
   
		new Thread(()->{ 
   
			while(true) { 
   
				LockSupport.park();
			}
		},"huihui_waiting").start(); //阻塞状态
		new Thread(()->{ 
   
			try { 
   
				Thread.sleep(100000);
			} catch (InterruptedException e){ 
   
				e.printStackTrace();
			}
		},"huihui_time_waiting").start(); //阻塞状态
	new Thread(new BlockClass(),"huihui_thread").start();
	new Thread(new BlockClass(),"huihui_block").start();
	}
	static class BlockClass extends Thread{ 
   
		public void run(){ 
   
			synchronized(BlockClass.class){ 
   
				try{ 
   
					Thread.sleep(1000000);
					} catch (InterruptedException e) { 
   
						e.printStackTrace();
					}
			}
		}
	}
}

Jetbrains全家桶1年46,售后保障稳定

查看状态:

  1. jps指令得到我程序的进程信息
    在这里插入图片描述
    得到我当前的进程为20376
  2. 通过jstack 20376得到线程的状态信息
    在这里插入图片描述

线程终止

刚才我们讲过,一个线程里面任务正常执行完毕,状态就是TERMINATED,就是终止状态。
但是,如果我线程里面的任务一直没有执行完成,我想去终止这个线程,或者我给点信息给到线程里,告诉线程我想终止结束呢!
所以我可以强制去关闭线程:线程提供一个stop方法,该方法不建议使用,已经过时了!!

因为stop是强行关闭线程,线程里面的任务都不在执行,不管线程的任务是否执行成功与否,就算执行到一半也会强制关闭!导致很多不可控制的
结果,比如支付付一半等等!!

所以我们要需要去优雅的关闭。什么叫做优雅关闭,就是我告诉你,我需要关闭了,但是我不强制关闭

线程里面提供了interrupt来优雅关闭,示例如下

package thread.demo.interrupt;
public class InterruptTest implements Runnable{ 
   
	@Override
	public void run() { 
   
		while (!Thread.currentThread().isInterrupted()) { 
   
		//false
			try { 
   
				Thread.sleep(100);
				} catch (InterruptedException e) { 
   
					e.printStackTrace();
					System.out.println("异常里的isInterrupted:"+Thread.currentThread().isInterrupted());
					Thread.currentThread().interrupt(); //再次中断
					System.out.println("再次中断:"+Thread.currentThread().isInterrupted());
				}
			}
		System.out.println("线程结束");
	}
	public static void main(String[] args) throws InterruptedException { 
   
		Thread t1=new Thread(new InterruptTest());
		t1.start();
		Thread.sleep(1000);
		//不中断,线程不进异常不中断,中断,线程会进入异常并且复位
		t1.interrupt();
	}
}

其思想:有个共享变量 类型boolean的isInterrupted,默认是false,然后外面可以改成true,线程里面可以获取到状态,如果是true,那么就说明外面有人想要我中断,那么如果我当前是waiting或者timewaiting状态,就会唤醒我的线程进入InterruptedException异常!!

interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?

  • interrupt() 优雅的通知线程需要结束,如果线程在waiting 会抛出InterruptedException,线程自己决定要不要结束,异常会触发复位

  • isInterrupted()获取线程的中断标记,但是不会进行复位操作

  • interrupted()获取线程的中断标记,并且主动执行复位操作

interrupted()示例如下:

public static void main(String[] args) throws InterruptedException { 
   
	Thread.currentThread().interrupt();
	System.out.println(Thread.interrupted()); //返回true,当前线程被interrupt
	System.out.println(Thread.currentThread().isInterrupted()); //获取线程的interrupt状态,本来应该是true,但是interrupted触发了复位,为false
}

线程状态的定义

其实Thread类下有JAVA层面对Thread状态的定义:

public enum State { 
   
	/** * Thread state for a thread which has not yet started. */
	NEW,
	/** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */
	RUNNABLE,
	/** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling *{@link Object#wait() Object.wait}. */
	BLOCKED,
	/** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> *<li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called <tt>Object.wait()</tt> * on an object is waiting for another thread to call * <tt>Object.notify()</tt> or <tt>Object.notifyAll() </tt> on * that object. A thread that has called <tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */
	WAITING,
	/** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: * <ul> * <li>{@link #sleep Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with timeout</li> *<li>{@link #join(long) Thread.join} with timeout</li> *<li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> *<li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */
	TIMED_WAITING,
	/** * Thread state for a terminated thread. * The thread has completed execution. */
	TERMINATED;
}

其实我们想一下,任何东西的生命周期都是开始与死亡!!
所以线程肯定有2种状态
初始(NEW)
新创建了一个线程对象,但是没有调用start()方法
终止(TERMINATED)
这个线程执行完毕
除了这2种状态外,线程还有以下几种状态
运行(RUNNABLE)
我们线程开启是需要start 的,所以初始化后,有个运行状态
等待(WAITING)
进入该状态的线程需要等待其他线程做出一些特定动作,线程进入了这个状态一般调用了

  • Object.wait() 需要等待另一个线程执行Object.notify()或者Object.notifyAll()
  • Thread.join() 需要等待线程执行完成
  • jpsLockSupport.park() 等待执行LockSupport.unpark(thread)

超时等待(TIMED_WAITING)
指定了时间后自行返回,等待一段时间后,会唤醒线程,而不是永久等待,一般执行过

  • Thread.sleep(long)
  • Object.wait(long)
  • Thread.join(long)
  • LockSupport.parkNanos()
  • LockSupport.parkUntil()

阻塞(BLOCKED)
线程阻塞于锁,比如synchronized

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/210040.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 腾讯云服务器php+mysq+nginx配置出现的问题及解决方法(亲测)

    腾讯云服务器php+mysq+nginx配置出现的问题及解决方法(亲测)

    2021年10月14日
  • 以太网用户侧接口(以太网协议转换方案)

    以太网接口示意图如下图1:以太网接口 如果您的职业生涯大部分时间都在从事PCB设计,并且您在计算机接口的布局和布线方面有经验,那么您就知道一件事是正确的:在器件应用说明中会有一些推荐的设计建议,并不是这些建议总是错误的,而是这些建议很容易断章取义。一位同事向我提出的一项建议是,在离散磁铁和连接器之间布线时,在RJ45连接器下方使用接地层。一些应用说明建议将系统接地覆盖RJ45连接器下方,一些应用说明建议将接地平面拆分为系统和机箱部分,以提供更强的隔离。应用说明中的一些建议指出,PHY、磁体和/或

  • CompareTo Semantics[通俗易懂]

    CompareTo Semantics[通俗易懂]ForthepropertytypesotherthanBOOLEAN,NAME,PATHandBINARY,comparisonrelationsaredefinedintermsoftheresultofthecompareTomethodoninstancesV1andV2oftheJavaclasscorrespondingto

  • 浅谈强化学习的方法及学习路线

    浅谈强化学习的方法及学习路线

  • 压缩文件密码暴力破解——cRARk使用方法

    压缩文件密码暴力破解——cRARk使用方法cRARk使用方法压缩文件如果忘记密码就需要使用暴力破解的方法进行破解,因为使用了加密的手段,是无法绕过密码验证的。cRARk是一款开源的功能强大的rar,7z类压缩软件的破解工具,支持GPU加速。官网地址目前有命令行版本和windows的GUI版本。使用方法在官网下载命令行版本GUI版本注意:GUI版本必须有命令行版本下才能运行GUI使用命令行版本下载解压,提示需要输入密码,但是实际上密码为空。或者为UTF-16。(crark55.rar)然后解压GUI版本,里面只有一个可运

  • C语言判断回文字符串(指针)

    C语言判断回文字符串(指针)东北大学在线编程社区problem1678题目描述:编写函数:intfun(char*p),功能是判断一个字符串是否是回文字符串(提示:回文字符串是指正读和反读都一样的字符串),要求从主函数中由键盘输入字符串,调用函数fun后,根据函数fun的返回值,主函数输出是否为回文字符串的判断。输入样例:haah输出样例:是回文串//该代码使用MicrosoftVisualStudio2019编写#define_CRT_SECURE_NO_WARNINGS#include<stdio.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号