公平鎖與非公平鎖
公平鎖:獲取鎖的先後順序與請求鎖的先後順序保持一致,具有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 []
可以看出,公平鎖獲取鎖的順序是嚴格按照請求順序的