经过上篇的实例 线程在陷入阻塞时,在sychronized获取互斥锁陷入阻塞时,我们是无法进行中断的,javase5中提供了一种解决的办法 ReentrantLock ,我们常常用到的是它的lock()unlock方法,但是这里要重点说的是它的lockInterruptibly()方法 这种获取锁的方式,具备在获取互斥锁陷入阻塞时可以中断该任务所在线程的能力,正常的lock()方法的运行机制是
尝试获取对象上的互斥锁 若获取成功,则标记该线程获取到了锁,然后返回,若获取失败,这时会将该线程阻塞并且放入等待获取这个对象互斥锁的队列,然后开始循环竞争互斥锁,若成功获取到了锁就会返回,若不成功则继续放入等待队列等待下一次竞争,一直到当前的线程获取到了锁,此时才会处理Interrupted标志,
而ockInterruptibly()获取锁的方式其实是稍稍有些改动 它是在每次竞争互斥锁的时候都会检查理Interrupted标志,若检测到了之后就会处理中断,所以具备竞争互斥锁阻塞时,随时可以中断的能力。
下面演示一下实例
模拟两个线程在争抢一个对象上的互斥锁
package test.thread.zhongjiahuayuan.interrupt.Lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** *演示ReentrantLock上阻塞的任务是可以被中断的 * @author Administrator * */ public class BlockedMutex { private Lock lock = new ReentrantLock(); public BlockedMutex() { //获取当前对象锁 try { lock.lockInterruptibly(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void f(){ try { //获取挡墙对象锁 //这种获取锁的方式在等待获取对象锁 被阻塞的时候是可以被中断的 lock.lockInterruptibly(); System.out.println("获取对象锁 在f()方法中"); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println("中断f"); } } } class Blocked2 implements Runnable{ BlockedMutex blocked = new BlockedMutex(); @Override public void run() { System.out.println("等待调用blocked的f方法"); blocked.f(); System.out.println("呼叫中断"); } }
测试中断
package test.thread.zhongjiahuayuan.interrupt.Lock; import java.util.concurrent.TimeUnit; public class Interrupting2 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Blocked2()); t.start(); TimeUnit.SECONDS.sleep(1); System.out.println("Issuing t.interrupt()"); t.interrupt(); } }