(一)ReentrantLock不公平鎖的幾個方法,以及對應的應用的場景。
直接上代碼:
public class TestReentrantLock implements Runnable {
public static ReentrantLock rtlk1 = new ReentrantLock();//預設的是false,不公平鎖
private ReentrantLock rtlk2 = new ReentrantLock(true);//公平鎖,與不公平鎖來說,要慢很多。
@Override
public void run() {
// tryLockTest(); //可能就隻列印一次。
// lockTest();//一定會列印兩次。
// tryLockTest();//逾時就傳回,可能隻列印一次。
lockInterruptTest();//中斷使用時間過長的操作。
}
public static void main(String[] args) {
TestReentrantLock t1 = new TestReentrantLock();
Thread tr1 = new Thread(t1);
Thread tr2 = new Thread(t1);
tr1.start();
tr2.start();
}
/*
1.0 (1)使用場景:①比如一個 定時任務, 第一次定時任務未完成, 重複發起了第二次,直接傳回flase;
②用在 界面互動時,點選執行較長時間請求操作時,防止多次點選,導緻背景重複執行。
* */
public static void tryLockTest() {
if (rtlk1.tryLock()) {//可能會立即傳回--->隻列印一次
//如果已經被lock,則立刻傳回false 就不會等待了,
//達到忽略操作的效果,當執行1000線程時,有些未獲得對象的線程,會自動跳過
try {
System.out.println("lk lk111 " + Thread.currentThread().getName());
} finally {
rtlk1.unlock();
}
}
}
/*
2.0 (2)同步操作 類似于synchronized 如果被其它資源鎖定,會在此等待鎖釋放,達到暫停的效果
ReentrantLock存在公平鎖與非公平鎖 而且synchronized都是公平的
* */
public static void lockTest() {
try {//會一直等待, 永遠列印兩次
rtlk1.lock();//如果被其它資源鎖定,會在此 等待 鎖釋放,達到暫停的效果
System.out.println("lk lk111 " + Thread.currentThread().getName());
} finally {
rtlk1.unlock();
}
}
/*
3. (3) 使用場景:(1)如果發現該操作正在執行,等待一段時間,
如果規定時間未得到鎖,放棄。防止資源處理不當,線程隊列溢出,出現死鎖
*/
public static void trylockTimeTest() {
try {
if (rtlk1.tryLock(5, TimeUnit.SECONDS)) { //如果已經被lock,嘗試等待5s,看是否可以獲得鎖,如果5s後仍然無法獲得鎖則傳回false繼續執行
try {
//操作
System.out.println("aaaa" + Thread.currentThread().getName());
} finally {
rtlk1.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace(); //目前線程被中斷時(interrupt),會抛InterruptedException
}
}
/*
4. (4.0) 使用場景:(1)中斷正在進行的操作,立刻釋放鎖,繼續下一操作.
比如 取消正在同步運作的操作,來防止不正常操作長時間占用造成的阻塞
**/
public static void lockInterruptTest(){
try {
rtlk1.lockInterruptibly();
//操作
System.out.println("aaaa"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rtlk1.unlock();
}
}
}