配色: 字号:
线程中断
2018-01-14 | 阅:  转:  |  分享 
  
线程中断机制

1、线程中断和线程终止的区别

2、判断线程是否被中断

3、线程中断在线程中的使用方法



1、线程中断和线程终止的区别

线程终止:当线程run()方法执行方法体中的最后一条语句后,并经执行return语句返回时,或出现方法没有捕获异常时线程终止。

线程中断:因为任何一个线程都不该被其他线程终止,所以我们引入Thread.interrupt()方法,来通知线程运行到某个地方该中断了,至于中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,由这个程序自身决定。



2、判断线程是否被中断

每个线程都具有boolean标志,用来判断是否到该被中断的位置了。中断线程的方法是:Thread.interrupt()方法。它将会设置该线程的中断状态标示位,并设置为true。线程会不时地检测这个中断标示位(判断某个线程是否已被发送过中断请求,使用

Thread.currentThread().isInterrupted()方法),来判断是否该提醒线程可以被中断了(即中断标示值是否为true)。

isInterrupted()方法和interrupt()方法区别:前者不会改变线程是否中断的属性值,后者可以将值设置为false,interrupt是一个静态方法,平时开发推荐使用isInterrupt()方法。

注意:synchronized在获锁的过程中是不能被中断的,意思是说如果产生了死锁,则不可能被中断

与synchronized功能相似的reentrantLock.lock()方法也是一样,它也不可中断的,即如果发生死锁,那么reentrantLock.lock()方法无法终止,如果调用时被阻塞,则它一直阻塞到它获取到锁为止。





3、线程中断在线程中的使用方法

Thread.interrupt()方法的作用是在线程受到阻塞时抛出一个中断信号,使线程退出阻塞状态。即:如果线程被Object.wait,Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(interruptedException),从而提早地终结被阻塞状态。

备注:Thread.sleep方法也可以产生InterruptedException,因此如果每次在做完工作后调用了sleep方法,可以不用检查isInterrupted,而是直接捕捉InterruptedException。



在中断发生后,线程仍然在运行时:

抛出InterruptException和用Thread.interrupted()唤醒阻塞,检查是否发生中断:

在阻塞操作时如:Thread.Sleep()时被中断,会抛出InterruptedException

代码如下:

publicclassInterruptTaskTest{

publicstaticvoidmain(String[]args)throwsException{

//将任务交给一个线程

//ATaska=newATask();

ATask1a1=newATask1();

//ATask2a2=newATask2();

//ATask3a3=newATask3();

Threadt=newThread(a1);

System.out.println("线程启动");

t.start();

//运行一段时间中断线程

//Thread.sleep(5000);

System.out.println("--线程停止--");

Thread.sleep(3000);

t.interrupt();//唤醒阻塞

System.out.println("t-inter");

}

}

classATask1implementsRunnable{

privatedoubled=0.0;

publicvoidrun(){

//死循环执行打印“等中断” try{

while(true){

System.out.println("本线程还活着");

for(inti=0;i<100;i++){

System.out.println("等中断"+i);

}

//中断一段时间后抛出InterruptedException

Thread.sleep(100);

}

}catch(InterruptedExceptione){

System.out.println("———本线程已中断———");

}

}

}



2)Thread.interrupted()检查是否发生中断。Thread.interrupted()能告诉我们线程是否发生中断,并将清除中断状态标记,唤醒阻塞,所以程序不会两次通知线程发生中断。

代码如下:

classATask2implementsRunnable{

publicvoidrun(){

//检查程序是否发生中断

while(!Thread.interrupted()){

System.out.println("等着看循环");

//Thread.sleep(5000);

for(inti=0;i<100;i++){

System.out.println("我还在运行"+i);

try{

Thread.sleep(1000);

System.out.println(System.currentTimeMillis());

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}

}



中断线程没发生:

如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的checkAccess方法就会被调用,这可能抛出SecurityException。如果线程在调用Object类的wait()、wait(long)或wait(long,int)方法,或者该类的join()、join(long)、join(long,int)、sleep(long)或sleep(long,int)方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException。

如果该线程在可中断的通道上的I/O操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个ClosedByInterruptException。

如果该线程在一个Selector中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的wakeup方法一样。

如果以前的条件都没有保存,则该线程的中断状态将被设置。

中断一个不处于活动状态的线程不需要任何作用。













献花(0)
+1
(本文系金银宝100首藏)