java 线程 interrupted_java线程之中断线程Interrupted用法

中断线程-interrupt()

一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法:

(1) Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。这些方法已经被废弃,使用它们是极端不安全的。

这里的 「stop」方法,和「resume」方法、「suspend」方法并称 Thread 三少,因为线程安全问题,都已经被 @Deprecated 了。。

当我们停止一个线程时,它会悄悄的把所持有的 monitor 锁释放了,此时,其他依赖锁的线程可能就会抢到锁执行。关键此时,当前 stop 的线程实际并没有处理完所有先决条件,可能这个时候就产生了诡异的问题,加班的日子可能就悄悄来了。

那你说 「Stop 不让用了,总得让我们有办法处理线程吧,哪怕通知他,打断他一下,让他停止」。

(2) Thread.interrupt() 方法是很好的选择。但是使用的时候我们必须好好理解一下它的用处。

//无法中断正在运行的线程代码

class TestRunnable implements Runnable{

public void run(){

while(true)

{

System.out.println( "Thread is running..." );

long time = System.currentTimeMillis();//去系统时间的毫秒数

while((System.currentTimeMillis()-time < 1000)) {

//程序循环1秒钟,不同于sleep(1000)会阻塞进程。

}

}

}

}

public class ThreadDemo{

public static void main(String[] args){

Runnable r=new TestRunnable();

Thread th1=new Thread(r);

th1.start();

th1.interrupt();

}

}

运行结果:一秒钟打印一次Thread is running...。程序没有终止的任何迹象 ,说明interrupt并不能中断线程执行。

首先我们看看interrupt究竟在干什么。

当我们调用th1.interrput()的时候,线程th1的中断状态(interrupted status) 会被置位。我们可以通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态。

在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 "。好好体会这句话的含义,看看下面的代码:

//Interrupted的经典使用代码

public void run(){

try{

....

while(!Thread.currentThread().isInterrupted()&& more work to do){

// do more work;

}

}catch(InterruptedException e){

// thread was interrupted during sleep or wait

}

finally{

// cleanup, if required

}

}

很显然,在上面代码中,while循环有一个决定因素就是需要不停的检查自己的中断状态。当外部线程调用该线程的interrupt 时,使得中断状态置位。这是该线程将终止循环,不在执行循环中的do more work了。

这说明: interrupt中断的是线程的某一部分业务逻辑,前提是线程需要检查自己的中断状态(isInterrupted())。

但是当th1被阻塞的时候,比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时。调用它的interrput()方法。可想而知,没有占用CPU运行的线程是不可能给自己的中断状态置位的。这就会产生一个InterruptedException异常。

//中断一个被阻塞的线程代码

class TestRunnable implements Runnable{

public void run(){

try{

Thread.sleep(1000000); //这个线程将被阻塞1000秒

}catch(InterruptedException e){

e.printStackTrace();

//do more work and return.

}

}

}

public class TestDemo2{

public static void main(String[] args) {

Runnable tr=new TestRunnable();

Thread th1=new Thread(tr);

th1.start(); //开始执行分线程

while(true){

th1.interrupt(); //中断这个分线程

}

}

}

/*运行结果:

java.lang.InterruptedException: sleep interrupted

at java.lang.Thread.sleep(Native Method)

at TestRunnable.run(TestDemo2.java:4)

at java.lang.Thread.run(Unknown Source)*/

强调一个知识:isInterrupted和interrupted区别

两者都是获取interrupt状态,但是interrupted方法在获取状态后,会重置状态。isInterrupted则不会重置状态。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值