多線程基礎(chǔ)(二)

一、線程同步

多個線程共享相同的數(shù)據(jù)或資源旨剥,就會出現(xiàn)多個線程爭搶一個資源的情況咧欣。這時就容易造成數(shù)據(jù)的非預(yù)期(錯誤)處理,是線程不安全的轨帜。

Java中對線程同步的支持魄咕,最常見的方式是添加synchronized同步鎖。
  • 給方法加鎖蚌父,稱為同步方法
  • 非靜態(tài)方法加鎖哮兰,鎖的是方法所屬的對象,即誰調(diào)用此方法就是誰苟弛。new不同對象時喝滞,因為鎖的對象不同,則不同步嗡午。
  • 靜態(tài)方法加鎖囤躁,鎖的是方法所屬的類,無論new多少都是一定具有同步效果的。
    -synchronized塊狸演,給方法某一部分加鎖言蛇,提高同步效率。this指的是調(diào)用此方法的對象宵距。如下例所示腊尚,this指的是調(diào)用run的線程
  • synchronized修飾不同方法或者代碼塊時,若多個線程看到的對象相同满哪,則這些方法間具有互斥性婿斥,不能并發(fā)運行。例如一個類中A/B方法上鎖哨鸭,不同線程分別調(diào)用A和B民宿,需要在A執(zhí)行完,B方可執(zhí)行
  • 集合工具類Collections可將線程非安全的集合轉(zhuǎn)為線程安全的像鸡。Ar'ra'y'list活鹰、linkedlist、hashset只估、hashmap都是線程不安全的志群。

舉例如下:

//售票系統(tǒng)
public class SaleService {
    private String ticketName;//票名
    private int totalCount;//總票數(shù)
    private int remaining;//剩余票數(shù)
    
    SaleService(String ticketName,int totalCount){
        this.ticketName = ticketName;
        this.totalCount = totalCount;
        this.remaining = totalCount;
    }
    public int synchronized sale(int ticketNum){
        if(remaining>0){
            remaining -= ticketNum;
            try {
                Thread.sleep(100);//暫停0.1秒,模擬真實系統(tǒng)中復(fù)雜計算所用的時間
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(remaining>=0){
                return remaining;
            }else{
                remaining += ticketNum;
                return -1;
            }
        }
        return -1;
    }
    public String getTicketName() {
        return ticketName;
    }
    public int getRemaining() {
        return remaining;
    }
}
//售票窗
public class TicketSaler implements Runnable{
    private String name;
    private SaleService saleService;

    TicketSaler(String name,SaleService saleService){
        this.name = name;
        this.saleService = saleService;
    }
    public void run() {
        while(saleService.getRemaining()>0){
            synchronized (this) {
                System.out.println(Thread.currentThread().getName()+"出售第"+saleService.getRemaining()+"票");
                int remaining = saleService.sale(3);
                if(remaining>=0){
                    System.out.println("出票成功蛔钙!剩余"+remaining+"張票");
                }else{
                    System.out.println("出票失斝吭啤!剩余"+saleService.getRemaining()+"張票");
                }
            }           
        }
    }
}
public static void main(String[] args) {
        SaleService service = new SaleService("廣州南-深圳", 50);
        TicketSaler saler = new TicketSaler("售票窗口",service);
        Thread threads[] = new Thread[5];
        for(int i=0;i<threads.length;i++){
            threads[i] = new Thread(saler, "窗口"+i);
            threads[i].start();         
        }       
    }

輸出如下:

image.png

如果去掉run方法中的鎖吁脱,則會發(fā)生資源安全問題桑涎!hava a try!
注意:只有sale方法的鎖豫喧,沒有run里的鎖石洗,是可以將sale方法鎖住,保證線程不能同時調(diào)用sale方法紧显,但有可能引起方法執(zhí)行完成后代碼塊的同步。比如窗口1執(zhí)行完sale缕棵,余票為2孵班,此時窗口2正在執(zhí)行,還未執(zhí)行完成招驴,窗口1執(zhí)行輸出的時候remaining可能剛好是-1了篙程,引起輸出錯誤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末别厘,一起剝皮案震驚了整個濱河市虱饿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖氮发,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渴肉,死亡現(xiàn)場離奇詭異,居然都是意外死亡爽冕,警方通過查閱死者的電腦和手機仇祭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颈畸,“玉大人乌奇,你說我怎么就攤上這事∶杏椋” “怎么了礁苗?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長徙缴。 經(jīng)常有香客問我寂屏,道長,這世上最難降的妖魔是什么娜搂? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任迁霎,我火速辦了婚禮,結(jié)果婚禮上百宇,老公的妹妹穿的比我還像新娘考廉。我一直安慰自己,他們只是感情好携御,可當(dāng)我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布昌粤。 她就那樣靜靜地躺著,像睡著了一般啄刹。 火紅的嫁衣襯著肌膚如雪涮坐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天誓军,我揣著相機與錄音袱讹,去河邊找鬼。 笑死昵时,一個胖子當(dāng)著我的面吹牛捷雕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壹甥,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼救巷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了句柠?” 一聲冷哼從身側(cè)響起浦译,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棒假,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后精盅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帽哑,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年渤弛,在試婚紗的時候發(fā)現(xiàn)自己被綠了祝拯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡她肯,死狀恐怖佳头,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晴氨,我是刑警寧澤康嘉,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站籽前,受9級特大地震影響亭珍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枝哄,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一肄梨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挠锥,春花似錦众羡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蓖宦,卻和暖如春齐婴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稠茂。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工柠偶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人主慰。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓嚣州,卻偏偏與公主長得像,于是被迫代替她去往敵國和親共螺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,446評論 2 359

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