自制樂(lè)觀鎖
例 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){
(購(gòu)買完整教程)
return flag;
}
void buyOne()
{
/*前面的三句,都只是get,想改只有updAtom里面,
你的buyOne只有改對(duì)和不改的權(quán)利,沒(méi)有改錯(cuò)的權(quán)利*/
int myVersion=numberVersion;
(購(gòu)買完整教程)
if(flag==1){
System.out.println("買一張成功");
}else{
System.out.println("已經(jīng)進(jìn)隊(duì)等了一會(huì),買一張失敗");
}
}
void buyBatch(int num)
{
int myVersion=numberVersion;
int myNumber=number;
(購(gòu)買完整教程)
}
}
馬克- to-win:馬克 java社區(qū):防盜版實(shí)名手機(jī)尾號(hào): 73203。
package com;
class MulThreMarkToWin extends Thread {
Ticket_Opti_MarkToWin ticOpti_MarkToWin;
(購(gòu)買完整教程)
}
class MulThreMarkToWinBatch extends Thread {
Ticket_Opti_MarkToWin ticOpti_MarkToWin;
(購(gòu)買完整教程)
}
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();
}
}
輸出結(jié)果是:
本來(lái)還剩4
最后還剩3
買一張成功
本來(lái)還剩3
最后還剩2
買一張成功
還沒(méi)排隊(duì),就發(fā)現(xiàn)不夠了,所以省時(shí)間了,撤了,買幾張失敗
本來(lái)還剩2
最后還剩1
買一張成功
輸出結(jié)果也有可能是:
本來(lái)還剩4
最后還剩1
買幾張成功
本來(lái)還剩1
最后還剩0
買一張成功
還沒(méi)排隊(duì),就發(fā)現(xiàn)不夠了,所以省時(shí)間了,撤了,買一張失敗
還沒(méi)排隊(duì),就發(fā)現(xiàn)不夠了,所以省時(shí)間了,撤了,買一張失敗
輸出結(jié)果也有可能是:
本來(lái)還剩4
最后還剩3
買一張成功
已經(jīng)進(jìn)隊(duì)等了一會(huì),買幾張失敗
已經(jīng)進(jìn)隊(duì)等了一會(huì),買一張失敗
本來(lái)還剩3
最后還剩2
買一張成功
結(jié)論:
馬克-to-win:不論是數(shù)據(jù)庫(kù)的select * from table for update; 還是我上面自制的緩存悲觀鎖,樂(lè)觀鎖的實(shí)現(xiàn),都有個(gè)共同的問(wèn)題:就是它們都是同步請(qǐng)求,都有可能一百萬(wàn)個(gè)線程卡在一個(gè)點(diǎn)上,死死等待,直到超時(shí),想退也退不出來(lái)。select * from table for update;是卡在數(shù)據(jù)庫(kù)的排他鎖上,而我上面自制的緩存悲觀鎖樂(lè)觀鎖的實(shí)現(xiàn),是卡在synchronized關(guān)鍵字上。馬克-to-win:那這個(gè)問(wèn)題怎么解決呢?就用我們java部分的線程那兒學(xué)的ReentrantLock的lockInterruptibly()方法,這個(gè)方法可以解決我們的 Ticket_Pess_MarkToWin悲觀鎖的問(wèn)題。而樂(lè)觀鎖和select for update的問(wèn)題還得自己手動(dòng)加隊(duì)列解決。在線程那章也有論述。綜合起來(lái),我還是傾向于ReentrantLock的悲觀鎖,因?yàn)樽约簩懙拇a少。馬克-to-win:不管悲觀樂(lè)觀,最終都得一個(gè)一個(gè)序列完成寫,寫的時(shí)間一樣。有關(guān)粗略的讀,就普通的看就夠了。要準(zhǔn)確的看,就加悲觀鎖就完了。