ReentrantLock中的lockInterruptibly()方法使得線程可以在被阻塞時響應中斷,比如一個線程t1通過lockInterruptibly()方法獲取到一個可重入鎖,並執行一個長時間的任務,另一個線程通過interrupt()方法就可以立刻打斷t1線程的執行,來獲取t1持有的那個可重入鎖。而通過ReentrantLock的lock()方法或者Synchronized持有鎖的線程是不會響應其他線程的interrupt()方法的,直到該方法主動釋放鎖之后才會響應interrupt()方法。下面看一個示例:
package com.lsl.common.lang;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* 測試ReentrantLock可中斷鎖的效果
*/
public class ThreadInteruptExample {
ReentrantLock lock1=new ReentrantLock();
ReentrantLock lock2=new ReentrantLock();
/**
* ReentrantLock響應中斷
* @throws Exception
*/
public void reentrantLockInterupt() throws Exception{
Thread t1=new Thread(new ReentrantLockTask(lock1,lock2));
Thread t2=new Thread(new ReentrantLockTask(lock2,lock1));
t1.start();
t2.start();
System.out.println(t1.getName()+"中斷");
//主線程睡眠1秒,避免線程t1直接響應run方法中的睡眠中斷
Thread.sleep(1000);
t1.interrupt();
//阻塞主線程,避免所有線程直接結束,影響死鎖效果
Thread.sleep(10000);
}
/**
* Synchronized響應中斷
* @throws Exception
*/
public void synchronizedInterupt() throws Exception{
Object syn1=new Object();
Object syn2=new Object();
Thread t1=new Thread(new SynchronizedTask(syn1,syn2));
Thread t2=new Thread(new SynchronizedTask(syn2,syn1));
t1.start();
t2.start();
System.out.println(t1.getName()+"中斷");
//主線程睡眠1秒,避免線程t1直接響應run方法中的睡眠中斷
Thread.sleep(1000);
t1.interrupt();
//阻塞主線程,避免所有線程直接結束,影響死鎖效果
Thread.sleep(1000);
}
/**
* ReentrantLock實現死鎖
*/
static class ReentrantLockTask implements Runnable{
ReentrantLock lock1;
ReentrantLock lock2;
public ReentrantLockTask(ReentrantLock lock1, ReentrantLock lock2){
this.lock1=lock1;
this.lock2=lock2;
}
@Override
public void run() {
try {
//可中斷的獲取鎖
lock1.lockInterruptibly();
//lock1.lock();
//睡眠200毫秒,保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待
TimeUnit.MILLISECONDS.sleep(200);
//lock2.lock();
//可中斷的獲取鎖
lock2.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock1.unlock();
lock2.unlock();
System.out.println("線程"+Thread.currentThread().getName()+"正常結束");
}
}
}
/**
* Synchronized實現死鎖
*/
static class SynchronizedTask implements Runnable{
Object lock1;
Object lock2;
public SynchronizedTask(Object lock1, Object lock2){
this.lock1=lock1;
this.lock2=lock2;
}
@Override
public void run() {
try {
synchronized (lock1){
//睡眠200毫秒,再獲取另一個鎖,
//保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待
Thread.sleep(200);
synchronized (lock2){
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println("線程"+Thread.currentThread().getName()+"正常結束");
}
}
}
public static void main(String[] args) throws Exception {
ThreadInteruptExample demo=new ThreadInteruptExample();
ThreadInteruptExample demo1=new ThreadInteruptExample();
demo.reentrantLockInterupt();
demo1.synchronizedInterupt();
}
}
響應中斷
執行完畢才響應中斷-現象死鎖

