自制樂觀鎖

例 2.2.1.2
package com;
public class Ticket_Opti_MarkToWin {
    private int number=4;
    private int numberVersion=0;
    private synchronized int updAtom(int num,int verNum)
    {
        int flag;
        if(numberVersion==verNum&&number>num){
(購買完整教程)
        return flag;
    }
  
    void buyOne()
    {
/*前面的三句,都只是get,想改只有updAtom里面,
 你的buyOne只有改對和不改的權利,沒有改錯的權利*/      
        int myVersion=numberVersion;
(購買完整教程)
        if(flag==1){
            System.out.println("買一張成功");
        }else{
            System.out.println("已經(jīng)進隊等了一會,買一張失敗");
        }
    }
  
    void buyBatch(int num)
    {
        int myVersion=numberVersion;
        int myNumber=number;
(購買完整教程)
    }
  
}




馬克- to-win:馬克 java社區(qū):防盜版實名手機尾號: 73203。

package com;
class MulThreMarkToWin extends Thread {
    Ticket_Opti_MarkToWin ticOpti_MarkToWin;
(購買完整教程)
}
class MulThreMarkToWinBatch extends Thread {
    Ticket_Opti_MarkToWin ticOpti_MarkToWin;
(購買完整教程)
}
public class TestConcurBuy_MarkToWin {
    public static void main(String[] args) {
        Ticket_Opti_MarkToWin ticOpti_MarkToWin=new Ticket_Opti_MarkToWin();
        Thread t1 = new MulThreMarkToWin(ticOpti_MarkToWin);
        Thread t2 = new MulThreMarkToWinBatch(ticOpti_MarkToWin);
        Thread t3 = new MulThreMarkToWin(ticOpti_MarkToWin);
        Thread t4 = new MulThreMarkToWin(ticOpti_MarkToWin);

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




輸出結果是:

本來還剩4
最后還剩3
買一張成功
本來還剩3
最后還剩2
買一張成功
還沒排隊,就發(fā)現(xiàn)不夠了,所以省時間了,撤了,買幾張失敗
本來還剩2
最后還剩1
買一張成功


輸出結果也有可能是:


本來還剩4
最后還剩1
買幾張成功
本來還剩1
最后還剩0
買一張成功
還沒排隊,就發(fā)現(xiàn)不夠了,所以省時間了,撤了,買一張失敗
還沒排隊,就發(fā)現(xiàn)不夠了,所以省時間了,撤了,買一張失敗


輸出結果也有可能是:


本來還剩4
最后還剩3
買一張成功
已經(jīng)進隊等了一會,買幾張失敗
已經(jīng)進隊等了一會,買一張失敗
本來還剩3
最后還剩2
買一張成功



結論:

馬克-to-win:不論是數(shù)據(jù)庫的select * from table for update; 還是我上面自制的緩存悲觀鎖,樂觀鎖的實現(xiàn),都有個共同的問題:就是它們都是同步請求,都有可能一百萬個線程卡在一個點上,死死等待,直到超時,想退也退不出來。select * from table for update;是卡在數(shù)據(jù)庫的排他鎖上,而我上面自制的緩存悲觀鎖樂觀鎖的實現(xiàn),是卡在synchronized關鍵字上。馬克-to-win:那這個問題怎么解決呢?就用我們java部分的線程那兒學的ReentrantLock的lockInterruptibly()方法,這個方法可以解決我們的 Ticket_Pess_MarkToWin悲觀鎖的問題。而樂觀鎖和select for update的問題還得自己手動加隊列解決。在線程那章也有論述。綜合起來,我還是傾向于ReentrantLock的悲觀鎖,因為自己寫的代碼少。馬克-to-win:不管悲觀樂觀,最終都得一個一個序列完成寫,寫的時間一樣。有關粗略的讀,就普通的看就夠了。要準確的看,就加悲觀鎖就完了。