線程(2)

7.線程的同步和鎖

為什么要進(jìn)行線程的同步薪者?

Java是允許多線程,當(dāng)多個(gè)線程操作同一個(gè)資源的時(shí)候玉吁,會(huì)導(dǎo)致得到或者打印的數(shù)據(jù)不準(zhǔn)確照弥。從而發(fā)生沖突。咋解決进副?加同步鎖这揣。

package com.wyx.c_suo;

//賣(mài)車(chē)票
class  MySycn implements Runnable{
    int ticket = 50;
    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "賣(mài)了第:" + ticket + "張票");
                ticket--;
            }else {
                System.out.println("賣(mài)完了");
                break;
            }
        }

    }
}

public class Demo1 {
    public static void main(String[] args) {
        MySycn mySycn = new MySycn();
        //多個(gè)線程操作同一資源,三個(gè)線程都去賣(mài)票
        new Thread(mySycn,"MySycn1線程").start();
        new Thread(mySycn,"MySycn2線程").start();
        new Thread(mySycn,"MySycn3線程").start();
    }
}


從運(yùn)行結(jié)果可以看出,第50張票三個(gè)線程都賣(mài)了给赞,不合法机打,正常生活邏輯應(yīng)該是只有一個(gè)線程在賣(mài)第50張這張票
解決方案:

1.同步方法:使用一個(gè)關(guān)鍵字synchronized修飾run方法。因?yàn)镴ava對(duì)象都有一個(gè)內(nèi)置的鎖對(duì)象塞俱。當(dāng)使用這個(gè)關(guān)鍵字的時(shí)候姐帚,修飾方法的時(shí)候吏垮,這個(gè)方法就會(huì)被鎖保護(hù)起來(lái)被鎖鎖住
當(dāng)一個(gè)線程進(jìn)來(lái)以后障涯,會(huì)立馬鎖住當(dāng)前的方法。意味著只有一個(gè)線程進(jìn)來(lái)膳汪,其他線程都在外面等著唯蝶。
語(yǔ)法格式:

@Override
public synchronized void run() {

}

會(huì)導(dǎo)致一種結(jié)果:假如線程1搶到了cpu,線程1會(huì)把循環(huán)執(zhí)行完遗嗽,也就是票賣(mài)完才會(huì)解開(kāi)鎖粘我,這個(gè)時(shí)候線程2搶到cpu,發(fā)現(xiàn)票已經(jīng)賣(mài)完痹换,直接就跳出了征字,線程3也一樣,會(huì)出現(xiàn)一家獨(dú)大的這種情況娇豫,也是不符合生活場(chǎng)景的,說(shuō)明不能在方法中加鎖匙姜,需要在其它地方加鎖。

換另外一種解決方法:
2.同步代碼塊:就是使用synchronized 關(guān)鍵字修飾一個(gè)語(yǔ)句塊冯痢。被修飾的語(yǔ)句塊會(huì)被加鎖氮昧。從而實(shí)現(xiàn)同步。
語(yǔ)法格式:

synchronized  (this) {

}

第一種方法浦楣,同步方法

package com.wyx.c_suo;

//賣(mài)車(chē)票
class  MySycn1 implements Runnable{
    int ticket = 50;
    @Override
    public synchronized void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "賣(mài)了第:" + ticket + "張票");
                ticket--;
            }else {
                System.out.println("賣(mài)完了");
                break;
            }
        }

    }
}

public class Demo2 {
    public static void main(String[] args) {
        MySycn1 mySycn1 = new MySycn1();
        //多個(gè)線程操作同一資源袖肥,三個(gè)線程都去賣(mài)票
        new Thread(mySycn1,"MySycn1線程").start();
        new Thread(mySycn1,"MySycn2線程").start();
        new Thread(mySycn1,"MySycn3線程").start();

        //使用一個(gè)關(guān)鍵字synchronized修飾run方法
        //假如線程1搶到了cpu,線程1會(huì)把循環(huán)執(zhí)行完振劳,也就是票賣(mài)完才會(huì)解開(kāi)鎖椎组,這個(gè)時(shí)候線程2搶到
        //cpu,發(fā)現(xiàn)票已經(jīng)賣(mài)完历恐,直接就跳出了庐杨,線程3也一樣,會(huì)出現(xiàn)一家獨(dú)大的這種情況夹供,也是不符合
        //生活場(chǎng)景的
    }
}


第二種方法灵份,同步代碼塊

package com.wyx.c_suo;

//賣(mài)車(chē)票
class  MySycn2 implements Runnable{
    int ticket = 50;
    @Override
    public void run() {
        //不能對(duì)循環(huán)加鎖,如果要是對(duì)循環(huán)加鎖哮洽,循環(huán)完才會(huì)釋放鎖填渠,還是出現(xiàn)一家獨(dú)大現(xiàn)象,
        //應(yīng)當(dāng)對(duì)if語(yǔ)句加鎖
        while (true) {
            synchronized (this) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "賣(mài)了第:" + ticket + "張票");
                    ticket--;
                }else {
                    System.out.println("賣(mài)完了");
                    break;
                }
            }
        }

    }
}

public class Demo3 {
    public static void main(String[] args) {
        MySycn2 mySycn2 = new MySycn2();
        //多個(gè)線程操作同一資源,三個(gè)線程都去賣(mài)票
        new Thread(mySycn2,"MySycn1線程").start();
        new Thread(mySycn2,"MySycn2線程").start();
        new Thread(mySycn2,"MySycn3線程").start();


    }
}



案例:

加鎖的目的為了保證數(shù)據(jù)的準(zhǔn)確性氛什。
賣(mài)電影票:
    三個(gè)線程:
        淘票票
        美團(tuán)
        貓眼
        總共有100張票莺葫,三家去賣(mài)
package com.wyx.c_suo;

class SaleTicket implements Runnable{
    //聲明一個(gè)變量,代表電影票當(dāng)前剩余量枪眉。
    private static int ticket = 100;
    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "賣(mài)了第" + ticket + "張票");
                    ticket--;
                }else {
                    System.out.println("賣(mài)完了");
                    break;
                }
            }
        }
    }
}
public class Demo4 {
    public static void main(String[] args) {
        SaleTicket saleTicket = new SaleTicket();
        new Thread(saleTicket,"淘票票").start();
        new Thread(saleTicket,"美團(tuán)").start();
        new Thread(saleTicket,"貓眼").start();

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捺檬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贸铜,更是在濱河造成了極大的恐慌堡纬,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒿秦,死亡現(xiàn)場(chǎng)離奇詭異烤镐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)棍鳖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)炮叶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人渡处,你說(shuō)我怎么就攤上這事镜悉。” “怎么了医瘫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵侣肄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我登下,道長(zhǎng)茫孔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任被芳,我火速辦了婚禮缰贝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘畔濒。我一直安慰自己剩晴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布侵状。 她就那樣靜靜地躺著赞弥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趣兄。 梳的紋絲不亂的頭發(fā)上绽左,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音艇潭,去河邊找鬼拼窥。 笑死戏蔑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲁纠。 我是一名探鬼主播总棵,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼改含!你這毒婦竟也來(lái)了情龄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捍壤,失蹤者是張志新(化名)和其女友劉穎骤视,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體白群,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尚胞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年硬霍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了帜慢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唯卖,死狀恐怖粱玲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拜轨,我是刑警寧澤抽减,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站橄碾,受9級(jí)特大地震影響卵沉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜法牲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一史汗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拒垃,春花似錦停撞、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至横堡,卻和暖如春埋市,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背命贴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工道宅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腊满,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓培己,卻偏偏與公主長(zhǎng)得像碳蛋,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子省咨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容