一.序言
ReentrantLock 锁有好几种,除了常用的lock tryLock 等意外,其中有个lockInterruptibly 用的比较少,看了下JDK 说明,官方的东西总是那么不容易理解,这里用稍微通俗的语言来描述一下。
二.栗子
1.我们用张三和李四 吃水果来描述:
如果张三吃苹果->休息5秒->吃香蕉
李四:发现张三在吃,就等待,直到李四吃完
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by qqr on 15/5/17.
*/
public class Lock {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new TaskThread());
t1.setName("张三 ");
Thread t2 = new Thread(new TaskThread());
t2.setName("李四 ");
t1.start();
Thread.sleep(100);// 保证先后顺序
t2.start();
Thread.sleep(100);
// 中断
t2.interrupt();
}
static class TaskThread implements Runnable{
// 所有线程都用同一把锁
static ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
try {
//
lock.lockInterruptibly();
System.out.println(Thread.currentThread().getName() + " 吃苹果");
Thread.sleep(5 * 1000);
System.out.println(Thread.currentThread().getName() + " 吃香蕉");
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 被中断了,没吃了");
}finally {
lock.unlock();
}
}
}
}
返回结果是:
张三 吃苹果
张三 吃香蕉
李四 吃苹果
李四 被中断了,没吃了
第一次如果用 lock() ,那么就是正常的逻辑:
张三持有锁的时候,李四没有获得锁,打断效果也会阻塞着,等张三吃完,李四吃苹果,然后被打断,就是上面结果了。
如果换成lockInterruptibly,那么结果是:
张三 吃苹果
李四 被中断了,没吃了
Exception in thread "李四 " java.lang.IllegalMonitorStateException
张三 吃香蕉
我们会发现,即使李四没有获得锁,也是可以被打断的, 这个区别是很明显的。
在linkedBlockingQuene 的put/take 方法中,我们可以看到类似这样的代码:
public void put(E e) throws InterruptedException {
// ....
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
notFull.await();
}
// ....
}
}
最为加锁的阻塞队列, 这里不允许多线程同时put,多线程对进入等待,但是用了lockInterruptibly,那么就意味着可以中断那些等待着的线程
四.小结
1.这里仅仅简单理解下他效果,可能并不全
2.遇到其他的场景 或者 解释有问题,请分享 和指出,谢谢。