自制乐观锁

例 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("已经进队等了一会,买一张失败");
        }
    }
  
    void buyBatch(int num)
    {
        int myVersion=numberVersion;
        int myNumber=number;
(购买完整教程)
    }
  
}

马克- to-win:马克 java社区:防盗版实名手机尾号: 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
买一张成功
还没排队,就发现不够了,所以省时间了,撤了,买几张失败
本来还剩2
最后还剩1
买一张成功


输出结果也有可能是:


本来还剩4
最后还剩1
买几张成功
本来还剩1
最后还剩0
买一张成功
还没排队,就发现不够了,所以省时间了,撤了,买一张失败
还没排队,就发现不够了,所以省时间了,撤了,买一张失败


输出结果也有可能是:


本来还剩4
最后还剩3
买一张成功
已经进队等了一会,买几张失败
已经进队等了一会,买一张失败
本来还剩3
最后还剩2
买一张成功



结论:

马克-to-win:不论是数据库的select * from table for update; 还是我上面自制的缓存悲观锁,乐观锁的实现,都有个共同的问题:就是它们都是同步请求,都有可能一百万个线程卡在一个点上,死死等待,直到超时,想退也退不出来。select * from table for update;是卡在数据库的排他锁上,而我上面自制的缓存悲观锁乐观锁的实现,是卡在synchronized关键字上。马克-to-win:那这个问题怎么解决呢?就用我们java部分的线程那儿学的ReentrantLock的lockInterruptibly()方法,这个方法可以解决我们的 Ticket_Pess_MarkToWin悲观锁的问题。而乐观锁和select for update的问题还得自己手动加队列解决。在线程那章也有论述。综合起来,我还是倾向于ReentrantLock的悲观锁,因为自己写的代码少。马克-to-win:不管悲观乐观,最终都得一个一个序列完成写,写的时间一样。有关粗略的读,就普通的看就够了。要准确的看,就加悲观锁就完了。