【2. Fair or Unfair It is a question...】
让我们继续前面有关ReentrantLock的话题。
首先,ReentrantLock有一个带布尔型参数的构造函数,在JDK官方文档中对它是这样描 述的:
“此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间 最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现 为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证 线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前 并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法 就可以获得成功。”
简单来讲:公平锁使线程按照请求锁的顺序依次获得锁;而不公平锁则允许讨价还价,在这种情况下,线程有 时可以比先请求锁的其他线程先得到锁。
观察采用公平锁和非公平锁的例程运行效果发现:线程获得锁的顺序发生了一些变化(见 下表)。
Unfair:
1 is running! 1 got lock1@Step1! 3 is running! 2 is running! 1 first Reading count:1 1 release lock1@Step1! 3 got lock1@Step1! 1 got lock2@Step2! thread 1 set age to:18 thread 1 first read age is:18 3 first Reading count:2 3 release lock1@Step1! 2 got lock1@Step1! thread 1 second read age is:18 1 release lock2@Step2! 3 got lock2@Step2! thread 3 set age to:34 thread 3 first read age is:34 2 first Reading count:3 2 release lock1@Step1! thread 3 second read age is:34 3 release lock2@Step2! 2 got lock2@Step2! thread 2 set age to:72 thread 2 first read age is:72 thread 2 second read age is:72 2 release lock2@Step2! 成功生成( 总时间:20 秒) |
Fair:
1 is running! 1 got lock1@Step1! 2 is running! 3 is running! 1 first Reading count:1 1 release lock1@Step1! 1 got lock2@Step2! thread 1 set age to:82 thread 1 first read age is:82 2 got lock1@Step1! 2 first Reading count:2 2 release lock1@Step1! 3 got lock1@Step1! thread 1 second read age is:82 1 release lock2@Step2! 2 got lock2@Step2! thread 2 set age to:65 thread 2 first read age is:65 3 first Reading count:3 3 release lock1@Step1! thread 2 second read age is:65 2 release lock2@Step2! 3 got lock2@Step2! thread 3 set age to:31 thread 3 first read age is:31 thread 3 second read age is:31 3 release lock2@Step2! 成功生成( 总时间:20 秒) |