JAVA_线程中断与InterruptedException
2018-08-21 本文已影响0人
Shokka
什么是线程中断:
要有线程中断,则需要有线程等待为前提:
等待1.当线程调用了sleep,wait,join方法时,线程都会进入阻塞状,等待被notify
等待2.线程正在获取锁并等待,进入阻塞状的线程可以显示调用Thread.interrupt()方法,让thread线程响应中断,注意:只有lock锁可以响应中断,使用synchronized关键字不可以。
中断1.当等待1情况响应了中断时,会抛出InterruptedException异常,并进入catch块中,这个时候就等于在catch中重新获取了线程的主导权,而不是等回复运行态获取主导权,InterruptedException异常可以处理也可以不处理。
中断2.当等待2情况响应了中断,会不会抛出InterruptedException异常,例如tryLock(long time, TimeUnit unit)方法会停止等待并直接返回false。
中断2的demo:
提问:对于lock.tryLock的响应中断,可以用try catch块嵌套 if (lock.tryLock(4,TimeUnit.SECONDS)),也可以直接在方法体throws InterruptedException,哪种比较好呢,希望你都试一试,自己去理解。
package org.kevin.lucene;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private static Lock lock = new ReentrantLock();
public void test(Thread currentThread) throws InterruptedException{
long now = System.currentTimeMillis();
if (lock.tryLock(4,TimeUnit.SECONDS)) {
try {
System.out.println(currentThread.getName()+"获取锁");
while(System.currentTimeMillis()-now < 10000) {
}
}
finally {
System.out.println(currentThread.getName()+"释放锁");
lock.unlock();
// TODO: handle finally clause
}
}else {
System.out.println(currentThread.getName()+"放弃获取锁");
}
}
public static void main(String[] args) {
LockTest test = new LockTest();
Thread t1 = new MyThread(test, "Thread--A");
Thread t2 = new MyThread(test, "Thread--B");
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.interrupt();
}
}
class MyThread extends Thread{
private LockTest test;
public MyThread(LockTest test,String threadName) {
super(threadName);
this.test = test;
}
public void run() {
System.out.println(this.getName()+" -》 进入了run方法");
try {
test.test(this);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("捕获终止异常");
e.printStackTrace();
}
}
}
如果用try catch块嵌套lock.tryLock(4,TimeUnit.SECONDS),则只能用两个try catch块
public void test(Thread currentThread){
long now = System.currentTimeMillis();
try {
if (lock.tryLock(4,TimeUnit.SECONDS)) {
try {
System.out.println(currentThread.getName()+"获取锁");
while(System.currentTimeMillis()-now < 10000) {
}
}
finally {
System.out.println(currentThread.getName()+"释放锁");
lock.unlock();
// TODO: handle finally clause
}
}else {
System.out.println(currentThread.getName()+"放弃获取锁");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
如果只用一个try catch块,则会出现A线程获取了锁,B线程正在等待锁,但是B线程中断了之后依然在finally中释放了锁的情况,会直接报错,如下:
public void test(Thread currentThread){
long now = System.currentTimeMillis();
try {
if (lock.tryLock(4,TimeUnit.SECONDS)) {
System.out.println(currentThread.getName()+"获取锁");
while(System.currentTimeMillis()-now < 10000) {
}
}else {
System.out.println(currentThread.getName()+"放弃获取锁");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
System.out.println(currentThread.getName()+"释放锁");
lock.unlock();
// TODO: handle finally clause
}
}