所谓的公平锁与非公平锁的区别在于等待的各个线程是否是公平的
对于公平锁来说,其内部维护了一个FIFO的队列,先申请的线程优先获取锁。而对于非公平锁来说,申请锁的线程可能插队,后申请锁的线程有可能先拿到锁。
因为线程从中断到继续执行需要花费大量的时间,甚至会产生时间。为了充分利用时间片,后申请锁的线程能够优先拿到锁,充分利用CPU时间。
但是对于处理时间远远大于排队等待时间的情形来说,使用非公平锁并不会带来多大的性能提升,反而使用公平锁能够增强对程序执行的控制。
在Java中,可重入锁可以指定锁是否是公平的:
public ReentrantLock(boolean fair)
下面是一个对公平锁和非公平锁的测试:
import org.junit.Test;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
private ReentrantLock notFairLock = new ReentrantLock(false);
private ReentrantLock fairLock = new ReentrantLock(true);
@Test
public void testFair(){
Thread[] threads = new Thread[10];
Runnable r = ()-> tryGet(fairLock);
for(int i=0;i<10;i++){
threads[i] = new Thread(r);
}
for(Thread t : threads){
t.start();
}
}
@Test
public void testNotFair(){
Thread[] threads = new Thread[10];
Runnable r = ()-> tryGet(notFairLock);
for(int i=0;i<10;i++){
threads[i] = new Thread(r);
}
for(Thread t : threads){
t.start();
}
}
private void tryGet(ReentrantLock lock){
try{
lock.lock();
System.out.println(Thread.currentThread().getName() + "获取了锁!");
}finally {
lock.unlock();
}
}
}