天天看點

ReentrantLock 不公平鎖介紹,以及的應用場景。

(一)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();
       }
   }

}      

繼續閱讀