您的位置:首页 > 编程语言 > Java开发

Java 多线程--interrupt()中断

2016-11-06 23:23 375 查看
Thread.interrupt()
方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.joinThread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(
InterruptedException
),从而提早地终结被阻塞状态

使用interrupt()中断线程

当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。

/**
* Created by yangtianrui on 16-11-1.
* #使用interrupt()中断线程:
* <p>
* 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,
* 该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,
* 如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。
* </p>
*/
public class InterruptTest {
public static void main(String[] args) {
Thread thread = new Thread(new SubThread());
thread.start();

//        try {
//            thread.sleep(2000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

thread.interrupt(); // 此处会将子线程的休眠中断, 此中断会引发InterruptException, 表示终端
System.out.println("Main exiting");
}
}

class SubThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " SubThread >> Sleep 50 seconds.");
try {
Thread.sleep(50000);
} catch (InterruptedException e) { // 处理中断信息
System.out.println(Thread.currentThread().getName() + " handle InterruptedException ");
}
// 继续执行
System.out.println("haha");
}
}

// output:
// Main exiting
// Thread-0 SubThread >> Sleep 50 seconds.
// Thread-0 handle InterruptedException
// haha


使用isInterrupted()方法判断中断状态

可以在Thread对象上调用
isInterrupted()
方法来检查任何线程的中断状态。这里需要注意:线程一旦被中断,isInterrupted()方法便会返回true,而一旦sleep()方法抛出异常,它将清空中断标志,此时isInterrupted()方法将返回false。

public class InterruptCheck extends Object{
public static void main(String[] args){
Thread t = Thread.currentThread();
System.out.println("Point A: t.isInterrupted()=" + t.isInterrupted());
//待决中断,中断自身
t.interrupt();
System.out.println("Point B: t.isInterrupted()=" + t.isInterrupted());
System.out.println("Point C: t.isInterrupted()=" + t.isInterrupted());

try{
Thread.sleep(2000);
System.out.println("was NOT interrupted");
}catch( InterruptedException x){
System.out.println("was interrupted");
}
//抛出异常后,会清除中断标志,这里会返回false
System.out.println("Point D: t.isInterrupted()=" + t.isInterrupted());
}
}

//isInterrupt=false
//isInterrupt=true
//isInterrupt=false


使用Thread.interrupted()方法判断中断状态

可以使用
Thread.interrupted()
方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么,这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。

public class InterruptReset extends Object {
public static void main(String[] args) {
System.out.println(
"Point X: Thread.interrupted()=" + Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println(
"Point Y: Thread.interrupted()=" + Thread.interrupted());
System.out.println(
"Point Z: Thread.interrupted()=" + Thread.interrupted());
}
}
//isInterrupt = false
//isInterrupt = true  自动重置标志位
//isInterrupt = false


待决中断

在上面的例子中,sleep()方法的实现检查到休眠线程被中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法前被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。

public class PendingInterrupt extends Object {
public static void main(String[] args){
//如果输入了参数,则在mian线程中中断当前线程(亦即main线程)
if( args.length > 0 ){
Thread.currentThread().interrupt();
}
//获取当前时间
long startTime = System.currentTimeMillis();
try{
Thread.sleep(2000);
System.out.println("was NOT interrupted");
}catch(InterruptedException x){
System.out.println("was interrupted");
}
//计算中间代码执行的时间
System.out.println("elapsedTime=" + ( System.currentTimeMillis() - startTime));
}
}


join 和 yield

join方法用线程对象调用,如果在一个线程A中调用另一个线程B的join方法,线程A将会等待线程B执行完毕后再执行。

yield可以直接用Thread类调用,yield让出CPU执行权给同等级的线程,如果没有相同级别的线程在等待CPU的执行权,则该线程继续执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: