Lock锁与synchronize关键字的区别:
1.Lock锁可以在我们需要的地方显式的调用,或者中断,以及超时获取锁等更加灵活的锁操作;但是失去了synchronize隐式获取与释放的便捷性.
2.Lock锁必须使用unLock释放,因此我们大多在finally代码块中释放.
//获取锁
void lock();
//获取锁过程中可以响应中断
void lockInterruptibly() throws InterruptedException;
//非阻塞式响应能够马上返回,获取锁返回true,反之false
boolean tryLock();
//超时获取锁,在超时time内或未中断情况下,可以获取锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//释放锁
void unlock();
//获取与lock绑定的等待通知组件,当前线程必须获取锁才能进行等待
//等待时释放锁,当再次获取锁才能从等待中返回
Condition newCondition();
3.Lock锁依赖volatile与AQS实现.
Lock可以理解为同步组件,而AQS是真正实现同步的操作;如果写自己的同步组件可以实现Sync静态内部类,如下(引用自
Doug Lea大师的例子):
//基础AQS的静态内存类
//重写方法
private static class Sync extends AbstractQueuedSynchronizer{
protected boolean isHeldExclusively() {
return getState() == 1;
}
//当state==0时,通过这获取锁
public boolean tryAcquire(int acquires) {
assert acquires == 1; //断言,如果不等于1,中断程序
if (compareAndSetState(0,1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//释放锁设置state == 0
protected boolean tryRelease(int releases) {
assert releases == 1;
if (getState() == 0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
//提供一个环境
Condition newCondition() {
return new ConditionObject();
}
//适当的反序列
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); //重置为未锁定状态
}
}
重写AQS的protected方法,依赖AQS的模板方法设计模式,实现在实现类获得是否获取/释放锁的指令,在AQS里面进行底层的操作.