概念:如果一个锁是公平的,那么锁的获取顺序,就应该符合请求的绝对时间顺序。即是说等待锁的队列中,排在队列最前面的那个线程将最先获得锁。如果一个锁是非公平的,那么则不要求锁的获取顺序一定严格遵循请求时间的顺序。
一、非公平锁实验设计;
1、充塞20个线程获取非公平锁;
2、在线程中打印当前线程名称和等待锁的线程列表;
3、待20个线程执行完毕,观察当前线程名称与等待锁的线程列表顺序是否一致;
4、代码如下:
public class FairAndUnFairLockTest {
public static void main(String[] args) {
FairAndUnFairLock lock = new FairAndUnFairLock(false);
for(int i = 0; i < 20; i++){
new Job(i+"", lock).start();
}
}
static class FairAndUnFairLock extends ReentrantLock{
public FairAndUnFairLock(boolean fair) {
super(fair);
}
public List<Thread> getQueuedThreads(){
List<Thread> list = new ArrayList<Thread>(super.getQueuedThreads());
Collections.reverse(list);
return list;
}
}
static class Job extends Thread{
private FairAndUnFairLock lock;
public Job(String name, FairAndUnFairLock fairLock) {
super(name);
this.lock = fairLock;
}
@Override
public void run() {
lock.lock();
try{
for(int i = 0; i < 1; i++){
System.out.print(Thread.currentThread().getName() + " obtain lock, ");
for(Thread thread : lock.getQueuedThreads()){
System.out.print(thread.getName()+" ");
}
System.out.print("wating lock.");
System.out.println();
}
}
finally{
lock.unlock();
}
}
}
}
5、实验结果如下:
等待锁的线程的顺序为1 2 3 4 5 6…线程,真实获得锁的线程的顺序为0 11 16 1 2…
这两者的顺序不一致,说明非公平锁的获取顺序并不符合请求的绝对时间的顺序。
二、公平锁实验设计;
1、充塞20个线程获取公平锁;
2、在线程中打印当前线程名称和等待锁的线程列表;
3、待20个线程执行完毕,观察当前线程名称与等待锁的线程列表顺序是否一致;
4、代码如下:
public class FairAndUnFairLockTest {
public static void main(String[] args) {
FairAndUnFairLock lock = new FairAndUnFairLock(true);
for(int i = 0; i < 20; i++){
new Job(i+"", lock).start();
}
}
static class FairAndUnFairLock extends ReentrantLock{
public FairAndUnFairLock(boolean fair) {
super(fair);
}
public List<Thread> getQueuedThreads(){
List<Thread> list = new ArrayList<Thread>(super.getQueuedThreads());
Collections.reverse(list);
return list;
}
}
static class Job extends Thread{
private FairAndUnFairLock lock;
public Job(String name, FairAndUnFairLock fairLock) {
super(name);
this.lock = fairLock;
}
@Override
public void run() {
lock.lock();
try{
for(int i = 0; i < 1; i++){
System.out.print(Thread.currentThread().getName() + " obtain lock, ");
for(Thread thread : lock.getQueuedThreads()){
System.out.print(thread.getName()+" ");
}
System.out.print("wating lock.");
System.out.println();
}
}
finally{
lock.unlock();
}
}
}
}
5、实验结果;
等待锁的线程的顺序为1 2 3 5 4 6 7,真实获得锁的线程的顺序为0 1 2 3 5 4 6 7,两者顺序一致,说明公平锁的获取是严格遵循线程请求锁的绝对时间的顺序的。
三、备忘;
1、ReentrantLock有公平锁、非公平锁的实现;
2、new ReentrantLock()默认是位非公平锁;
3、非公平锁的性能,是远大于公平锁的。除非必要,否则应优先非公平锁的使用。