1. 程式人生 > >樂觀鎖(Pessimistic)與悲觀鎖(Optimistic)

樂觀鎖(Pessimistic)與悲觀鎖(Optimistic)

結論

其實樂觀鎖(Optimistic)和悲觀鎖是對讀和寫而言的,悲觀鎖(Pessimistic)是讀有優勢,而樂觀鎖鎖則是寫有優勢.
所以樂觀鎖時候寫少的情況,悲觀鎖時候讀少的情況.

悲觀鎖

悲觀鎖是指在用讀取鎖鎖定一塊程式碼的時候,另一個讀取鎖依然可以進入該程式碼塊,而寫鎖不可以進入.在用寫鎖鎖定一段程式碼的時候,讀鎖和寫鎖都不能進入該程式碼塊.

樂觀鎖

樂觀鎖其實就是寫鎖優先機制,讀鎖在鎖定某一程式碼塊的時候,如果沒有寫鎖競爭,那麼就會獲得該鎖的許可權,如果進行鎖定的時候發現有寫鎖正在競爭,那麼就會丟擲例外,需要重新操作進行鎖定.競爭標誌則是
long stamp = lock.tryOptimisticRead();//有競爭返回0
lock.validate(stamp);//有競爭返回true

以下是程式碼驗證:

悲觀鎖示例

package Test;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Main {
    public static void main(String[] args) {
        Pessimistic p = new Pessimistic();
        Thread t1=new Thread(()->{
            p.addSome();
        })
; Thread t2=new Thread(()->{ p.getSome(); }); Thread t3=new Thread(()->{ p.getSome(); }); t1.start(); t2.start(); t3.start(); } } class Pessimistic{ private ReadWriteLock lock = new ReentrantReadWriteLock
(); public void addSome() { lock.writeLock().lock(); try { System.out.println("addSome方法被我鎖啦,我要霸佔這把鎖2s鍾"); Thread.sleep(2000); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally { lock.writeLock().unlock(); } } public void getSome() { lock.readLock().lock(); try { System.out.println("getSome方法被我鎖啦,我要霸佔這把鎖2s鍾"); Thread.sleep(2000); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally { lock.readLock().unlock(); } } } /*------------------------------------- 結果: addSome方法被我鎖啦,我要霸佔這把鎖2s鍾 //間隔兩秒 getSome方法被我鎖啦,我要霸佔這把鎖2sgetSome方法被我鎖啦,我要霸佔這把鎖2s鍾 情況2: getSome方法被我鎖啦,我要霸佔這把鎖2sgetSome方法被我鎖啦,我要霸佔這把鎖2s鍾 //間隔兩秒 addSome方法被我鎖啦,我要霸佔這把鎖2s鍾 ------------------------------------*/

樂觀鎖示例

package Test;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

public class Main {
    public static void main(String[] args) {
        Optimistic p = new Optimistic();
        Thread t1=new Thread(()->{
            p.addSome();
        });
        Thread t2=new Thread(()->{
            p.getSome();
        });

        Thread t3=new Thread(()->{
            p.getSome();
        });

        t1.start();
        t2.start();
        t3.start();


    }

}


class Pessimistic{
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public void addSome() {
        lock.writeLock().lock();

        try {
            System.out.println("addSome方法被我鎖啦,我要霸佔這把鎖2s鍾");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }


    public void getSome() {
        lock.readLock().lock();

        try {
            System.out.println("getSome方法被我鎖啦,我要霸佔這把鎖2s鍾");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}


class Optimistic{
    private StampedLock lock =new StampedLock();
    public void addSome() {
        long stamp=lock.writeLock();
        try {
            System.out.println("addSome方法被我鎖啦,我要霸佔這把鎖2s鍾");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.unlockWrite(stamp);
        }
    }


    public void getSome() {
        long stamp = lock.tryOptimisticRead();//如果有其他鎖,戳記會為0
        try {
            if(!lock.validate(stamp)) {
                stamp=lock.readLock();
                System.out.println("getSome方法被我鎖啦,我要霸佔這把鎖2s鍾");
                Thread.sleep(2000); 
            }
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            try {

                lock.unlockRead(stamp);
            }catch (Exception e) {
                // TODO: handle exception
                System.out.println("已經被write鎖鎖了");
            }
        }
    }
}


/*------------------------------------
結果
情況1://大多數情況
addSome方法被我鎖啦,我要霸佔這把鎖2s鍾
//間隔兩秒鐘
getSome方法被我鎖啦,我要霸佔這把鎖2sgetSome方法被我鎖啦,我要霸佔這把鎖2s鍾


情況2:
已經被write鎖鎖了
addSome方法被我鎖啦,我要霸佔這把鎖2sgetSome方法被我鎖啦,我要霸佔這把鎖2s鍾
------------------------------------*/