天天看点

并发编程12-显示锁

内部所拥有比较好的性能,但是在灵活性方面有缺陷,并且如果申请锁失败就会陷入阻塞等待的过程中。

对于一些场景,我们可以使用显示锁lock

lock 的lock方法相当于进入同步块, unlock方法相当于退出同步块。支持跟内部锁同样的重入机制:

可以看出内部锁的代码还有清爽一点, 显示锁需要在finally中释放

先看下死锁的情况:

改为不会死锁的情况:

如上其实主要是利用了trylock当获取不到锁就返回false的特性。另外trylock还能设置超时时间,指定时间得不到锁才返回false.

当代码遇到锁标记有很多种选择,获得锁,如果锁不再了等待锁,重入进该锁, 响应中断。

通常的锁在需要等待的时候并不会响应中断。

如下:

使用lock()的返回结果:

使用lockinterruptibly()的返回结果:

可见lockinterruptibly与普通锁的区别在于可以在锁等待的时候响应中断

在jdk6之前性能上lock要好很多,但是jdk6之后改进了内部锁的算法,现在差不多

reentrantlock锁的构造器中可以选择是否公平,公平的意思就是开始执行的顺序将会按照锁等待的顺序。这样会造成性能下降,只有在对顺序敏感的时候才需要。

性能上jdk1.6,reentrantlock略好。

reentrantlock可以支持复杂的语义。

reentrantlock需要显示关闭

synchronized语法上更简单易用

综上,其实应该更多的使用synchoronized,只有在有必要的时候才使用reentrantlock

普通的锁限制了并发性,对于数据无害的读-读操作也会出现锁竞争。这个时候可以使用读写锁

读写锁的一些特性:

- 基本功能就是有写入的时候要等写完完成才能再执行写入,如果没有写入的时候读是可以并发的

- 可降级不可以升级,就是读解锁前如果获取写锁会死锁,但是写锁中是可以获取读锁的

- 各锁单独可重入

可以验证写锁互斥,读写并发。

继续阅读