java 线程 interrupt_JAVA多线程的interrupt()方法介绍

这篇文章再来讲一些JAVA多线程中不常用,但是实际上又很重要的一些小方法,如果对多线程的其他知识有兴趣,可以翻看我的其他文章,兴许能够对您的多线程的学习添砖加瓦~

再说interrupt()方法前,我想给大家介绍一下线程的结束的原理帮助大家来深刻的理解一下interrupt()方法的出现

中断结束的原理

我们理论上只需要让run()停止运行,那么线程就结束了

我看了网上很多其他大佬写的帖子,基本上一上来就给大家写一个while()或者for()循环,然后在里面写interrup()来停止

事实上确实是,我写的帖子主要是针对初学者,我相信大佬也不需要看我的帖子了

我随意从网上赋值一下大佬写的示例代码(如有冒犯,实属抱歉,只是为了把原因说清楚):

public class ThreadTest implements Runnable {

public static void main(String[] args) throws InterruptedException {

Thread thread = new Thread(new ThreadTest());

thread.start();

Thread.sleep(500);

thread.interrupt();

}

@Override

public void run() {

while (true) {

try {

System.out.println("try:"+Thread.currentThread().isInterrupted());

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("catch:"+Thread.currentThread().isInterrupted());

}

}

}

}

网上大部分大佬的帖子都是类似的,用了一个循环然后来打断循环,为什么要使用循环,原因也很简单

线程的提出主要就是针对循环等费时间的程序,如果是顺序执行代码,单线程完全可以自己实现,没有什么必要写多线程

只要原因了,我也会在下面的示例代码中用循环操作

既然是循环操作,那么是不是意味着我们如果能够把线程中的循环等费时操作给打断,那么线程不就可以很快结束了吗?顺寻执行代码速度很快,大家没意见吧。

在没有引入interrupt()的情况下,我们来打断线程

/*

需求:通过改变标记来停止线程的运行

*/

public class interruptDemo implements Runnable{

private boolean flag=true;

public void run() {

int count=0;

while(flag)

{

System.out.println("I am run!"+count++);

}

System.out.println("over");

}

void setflag(boolean flag) {

this.flag=flag;

}

}

import java.util.LinkedList;

public class TestDemo {

public static void main(String[] args) {

interruptDemo in=new interruptDemo();

Thread t=new Thread(in);

t.start();

for(int i=0;i<100;i++)

{

System.out.println("I am main"+i);

}

in.setflag(false);

}

}

大家可以试试,运行会很完美,线程执行一半就会停止下来,我们已经成功的通过改变标记来停止线程了

wait()等方法剥夺CPU

当然其实并不是所有的线程都可以这样子停止

比如说这样

/*

需求:通过改变标记来停止线程的运行

*/

public class interruptDemo implements Runnable{

private boolean flag=true;

public void run() {

function();

}

synchronized void function()

{

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

int count=0;

while(flag)

{

System.out.println("I am run!"+count++);

}

System.out.println("over");

}

void setflag(boolean flag) {

this.flag=flag;

}

}

这里把子线程的打印单独拎出来了,然后再加了this锁,保证每次只有一个线程进行访问,里面加了wait()方法,运行到了wait()就会挂起,被剥夺了执行权限

很显然这种情况下,我们没办法把子线程停止,它会一直挂起

本质原因在于子线程被剥夺了执行资格(CPU),没办法继续执行

所以我们的办法就是我们要让它再次恢复资格

这才是真正为什么要引出interrupt()的根本原因

interrupt()

对于线程的执行,大家都很清楚最基本的三个状态:就绪、运行、结束,分别对应的方法是start()、run()、stop()

但是很遗憾由于stop()存在一些安全问题,已经过时弃用了,那么我们需要找出一种合适的方法来代替stop()

interrupt()的功能就是让线程再次获得执行权限,打断wait、join()、sleep()等方法

最终的代码会是这样子

/*

需求:通过改变标记来停止线程的运行

*/

public class interruptDemo implements Runnable{

private boolean flag=true;

public void run() {

function();

}

synchronized void function()

{

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

System.out.println("我被打断了");//wait()打断后会抛出异常

}

int count=0;

while(flag)

{

System.out.println("I am run!"+count++);

}

System.out.println("over");

}

void setflag(boolean flag) {

this.flag=flag;

}

}

public class TestDemo {

public static void main(String[] args) {

interruptDemo in=new interruptDemo();

Thread t=new Thread(in);

t.start();

for(int i=0;i<100;i++)

{

System.out.println("I am main"+i);

}

in.setflag(false);

t.interrupt();//打断挂起,让子线程再次获得执行权限

}

}

这里通过interrupt打断线程的沉睡

网上很多都提到了isinterrupted,这个仅仅是一种标记而已,和flag类似,但是它在抛出后又恢复原来的值

那么使用interrupted就是这样的

/*

需求:通过改变标记来停止线程的运行

*/

public class interruptDemo implements Runnable{

private boolean flag=true;

public void run() {

function();

}

synchronized void function()

{

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

System.out.println("我被打断了");//wait()打断后会抛出异常

}

int count=0;

System.out.println(Thread.interrupted());

while(Thread.interrupted())

{

System.out.println("I am run!"+count++);

}

System.out.println(Thread.interrupted());

System.out.println("over");

}

void setflag(boolean flag) {

this.flag=flag;

}

}

public class TestDemo {

public static void main(String[] args) {

interruptDemo in=new interruptDemo();

Thread t=new Thread(in);

t.start();

for(int i=0;i<100;i++)

{

System.out.println("I am main"+i);

}

in.setflag(false);

t.interrupt();//打断挂起,让子线程再次获得执行权限

}

}

总结

stop()由于存在安全问题已经弃用

多线程是用来解决某些耗时操作,我们可以通过打断耗时操作来结束线程

interrupt()并不是真正的让线程停下来,它其实只是改变了一下执行标记,最终还是需要我们来完成线程的停止

isinterruped就是一种内部标记和interrupt()配合使用

wait、join()、sleep()剥夺执行权限之后,interrupt可以中断这种挂起

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值