1. 程式人生 > >ReentrantLock的四種加鎖方式

ReentrantLock的四種加鎖方式

java中使用顯示的Lock物件時候必須被顯示的建立,鎖定和釋放。因此它與內健的鎖形式相比,程式碼缺乏優雅性,但是它也比較靈活。
*

 
* class X {
* private final ReentrantLock lock = new ReentrantLock();
* // ...
*
* public void m() {
* lock.lock(); // block until condition holds
* try {
* // ... method body
* } finally {
* lock.unlock()
* }
* }
* }
*

*
這裡是jdk中的一個簡單的使用方法。由此可見它的使用套路,能夠捕獲異常的優點。以上只是使用了lock方法去加鎖,現在一一介紹它的加鎖方式。

一、lock.lock();

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.

在等待獲取鎖的過程中休眠並禁止一切執行緒排程

二、void lockInterruptibly() throws InterruptedException;

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:
The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported.

在等待獲取鎖的過程中可被中斷

三、boolean tryLock();

Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false.

獲取到鎖並返回true;獲取不到並返回false

四、boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

If the lock is available this method returns immediately with the value true. If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or The specified waiting time elapses.

然後執行程式碼看看
測試類如下

public class AttemptLocking {
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 
     * @description
     * 
     */
    public void tLock() {
        lock.lock();
        try {
            System.out.println("mathod lock is not available");
            Thread.sleep(5000);
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            lock.unlock();
            System.out.println("mathod lock is available");

        }
    }

    /**
     * 
     * @description
     */
    public void tTryLock() {
        boolean captured = lock.tryLock();//
        try {
            if (captured) {
                System.out.println("mathod tryLock is not available");
                Thread.sleep(3000);
            } else {
                System.out.println("mathod tryLock is available--");
            }
        } catch (InterruptedException e) {
            System.out.println("mathod tryLock throw InterruptedExecption");
        } finally {
            if (captured) {
                lock.unlock();
                System.out.println("mathod tryLock is available");
            }
        }
    }

    /**
     * 
     * @description
     */
    public void tTryLock2() {
        boolean captured = false;
        try {
            captured = lock.tryLock(6, TimeUnit.SECONDS);
            if (captured) {
                System.out.println("mathod tryLock2 is not available");
            } else {
                System.out.println("mathod trylock2 is available++");
            }
        } catch (InterruptedException e) {
            System.out.println("mathod trylock2 throw InterruptedException");
        } finally {
            if (captured) {
                lock.unlock();
                System.out.println("mathod trylock2 is available");
            }
        }
    }

    public void tInterruptLock(){
        try {
            lock.lockInterruptibly();
            System.out.println("mathod interruptlock is not available");
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            System.out.println("mathod interruptlock throw InterruptException");
        }finally{
            if(lock.isLocked()){
                lock.unlock();
                System.out.println("mathod interruptlock is available");
            }
        }
    }
}

呼叫類如下

public class Text{

 static Thread A=null;
 static Thread B=null;
public static void main(String[] args) {
        // TODO Auto-generated method stub
        final AttemptLocking al = new AttemptLocking();
        A=new Thread(new Runnable() {
            public void run() {
                //case1,2,3,4
                al.tLock();
            }
        });
        B=new Thread(new Runnable() {

            @Override
            public void run() {
                //case1
//              al.tLock();//等待的過程中呼叫中斷不會中斷,當進入時候呼叫中斷會丟擲中斷異常的
                //case2
//              al.tTryLock();//可以修改睡眠時間為4s和6s,立即返回不用測試中斷
                //case3
//              al.tTryLock2();//可以修改睡眠時間為4s和6s,等待的時候可以中斷
                //case4
                al.tInterruptLock();//丟擲中斷異常
            }
        });
        A.setName("a");
        B.setName("b");
        A.start();
        B.start();
        //case1,3,4
//      B.interrupt();
    }
}

在指定時間內等待獲取鎖;過程中可被中斷

假如執行緒A和執行緒B使用同一個鎖LOCK,此時執行緒A首先獲取到鎖LOCK.lock(),並且始終持有不釋放。如果此時B要去獲取鎖,有四種方式:

LOCK.lock(): 此方式會始終處於等待中,即使呼叫B.interrupt()也不能中斷,除非執行緒A呼叫LOCK.unlock()釋放鎖。
LOCK.lockInterruptibly(): 此方式會等待,但當呼叫B.interrupt()會被中斷等待,並丟擲InterruptedException異常,否則會與lock()一樣始終處於等待中,直到執行緒A釋放鎖。
LOCK.tryLock(): 該處不會等待,獲取不到鎖並直接返回false,去執行下面的邏輯。
LOCK.tryLock(10, TimeUnit.SECONDS):該處會在10秒時間內處於等待中,但當呼叫B.interrupt()會被中斷等待,並丟擲InterruptedException。10秒時間內如果執行緒A釋放鎖,會獲取到鎖並返回true,否則10秒過後會獲取不到鎖並返回false,去執行下面的邏輯。