公平锁与非公平锁
公平锁:获取锁的先后顺序与请求锁的先后顺序保持一致,具有FIFO特点。
非公平锁:反之则为非公平锁。
什么是可重入?
同一个线程重复多次获取同一把锁,释放的时候也需要释放多次。
Java中锁的特点
synchronized:可重入,非公平(不可设置)。锁的是Object对象
ReentrantLock:可重入,公平或非公平(可设置)。通过获取同步状态来获取锁,并非通过设置Object对象头来获取锁。
公平锁测试
package concurrent.ReentrantLock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @基本功能:测试公平锁和非公平锁
* @program:summary
* @author:peicc
* @create:2019-10-08 13:11:50
**/
public class FairAndUnfairTest {
private static Lock fairLock=new ReentrantLock2(true);// 公平锁
private static Lock unfairLock=new ReentrantLock2(false);// 非公平锁
private static CountDownLatch count=new CountDownLatch(1);
private static class Job extends Thread{
private Lock lock;
public Job(Lock lock) {
this.lock=lock;
}
@Override
public void run() {
try {
count.await();
}
catch (InterruptedException e) {
}
for (int i = 0; i <2 ; i++) {
lock.lock();
try {
System.out.print("Lock by ["+getName()+ "], Waiting by [" /*+ ((ReentrantLock2) lock).getQueuedThreads()*/);
ArrayList<Thread> list=(ArrayList<Thread>) ((ReentrantLock2) lock).getQueuedThreads();
for (int j = 0; j <list.size() ; j++) {
System.out.print(list.get(j).getName()+",");
}
System.out.println("]");
} finally {
lock.unlock();
}
}
}
}
private static void testLock(Lock lock){
for (int i = 0; i <5 ; i++) {
Thread thread=new Job(lock);
thread.setName(""+i);
thread.start();
}
count.countDown();
}
/*********
*内部类
*/
private static class ReentrantLock2 extends ReentrantLock{
/***
* @函数功能:构造函数
* @param fair:
* @return:
*/
public ReentrantLock2(boolean fair){
super(fair);
}
@Override
public Collection<Thread> getQueuedThreads() {
List<Thread> list=new ArrayList<>(super.getQueuedThreads());
Collections.reverse(list);
return list;
}
}
public static void main(String[] args) {
System.out.println("-------------------公平锁测试-----------------");
testLock(fairLock);
/* System.out.println("-------------------非公平锁测试-----------------");
testLock(unfairLock);*/
}
}
运行结果
-------------------公平锁测试-----------------
Lock by [2], Waiting by [3,]
Lock by [3], Waiting by [1,0,]
Lock by [1], Waiting by [0,3,2,]
Lock by [0], Waiting by [3,2,1,4,]
Lock by [3], Waiting by [2,1,4,0,]
Lock by [2], Waiting by [1,4,0,]
Lock by [1], Waiting by [4,0,]
Lock by [4], Waiting by [0,]
Lock by [0], Waiting by [4,]
Lock by [4], Waiting by []
可以看出,公平锁获取锁的顺序是严格按照请求顺序的