转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/47679007
在上一篇博客中,我们讨论了Race Condition现象以及它产生的原因,现在我们知道它是不好的一种现象了,那么我们有什么方法避免它呢。最直接有效的方式就是放弃多线程,直接改为使用单线程但操作数据,但是这是不优雅的,因为我们知道有时候,多线程有它自己的优势。在这里我们讨论两种其他的方法——锁对象和条件对象。
锁对象
java SE5.0之后为实现多线程的互斥引入了ReentrantLock类。ReentrantLock类一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
ReentrantLock类有两种构造方法:
构造方法
一、不带公平参数的构造方法
private ReentrantLock lock = new ReentrantLock();
默认的是非公平锁,这种锁不会根据线程等待时间的长短来优先调度线程。
这样就构造了一个锁对象lock。
二、带公平参数的锁对象
private ReentrantLock lock = new ReentrantLock(true);
此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。
公平锁和非公平锁的区别:
与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。
使用方法
class X {
private final ReentrantLock lock = new ReentrantLock();
// 其他变量的定义
public void m() {
lock.loc