當多個執行緒同時共享同乙個全域性變數或靜態變數,做寫的操作時,可能會發生資料衝突問題,也就是執行緒安全問題。
舉個案例來說:現在有100張火車票,有兩個視窗同時搶火車票,使用多執行緒模擬搶票效果。
/**
* @classdesc: 功能描述:(多執行緒之買火車票案例-展示執行緒不安全問題)
*/class threadtrain implements runnable catch (interruptedexception e)
sale();
}} /**
* @methoddesc: 功能描述:(**火車票)
*/public void sale() catch (exception e)
system.out.println(thread.currentthread().getname() + "**第" + (100 - traincount + 1) + "張票");
traincount--; }}
}public class threaddemo
}
執行結果:
一號視窗和二號視窗同時**第一張和第七張火車票,部分火車票會重複**。
結論發現:多個執行緒共享同乙個全域性成員變數時,做寫的操作可能會發生資料衝突問題。
使多執行緒之間同步或使用鎖(lock)
將可能會發生資料衝突問題(執行緒不安全問題)的**,只讓當前乙個執行緒進行執行。**執行完成後釋放鎖,釋放之後才能讓其他執行緒執行,這樣就可以解決執行緒不安全問題。
當多個執行緒共享同乙個資源,而不會受到其他執行緒的干擾。
第一種:使用同步**塊
什麼是同步**塊?
同步**塊就是將可能會發生執行緒安全問題的**給包裹起來
private object obj = new object();// 自定義多執行緒同步鎖
public void sale() catch (exception e)
system.out.println(thread.currentthread().getname() + "**第" + (100 - traincount + 1) + "張票");
traincount--; }}
}
第二種:使用同步函式什麼是同步函式?
使用synchronized 修飾的函式稱為同步函式
public synchronized void sale() catch (exception e)
system.out.println(thread.currentthread().getname() + "**第" +(100 - traincount + 1) + "張票");
traincount--;}}
動腦筋思考一下,同步函式使用的是什麼鎖?怎樣證明呢?同步函式使用this鎖
證明方式: 乙個執行緒使用同步**塊(this明鎖),另乙個執行緒使用同步函式。如果兩個執行緒能實現同步,說明同步函式使用的是this鎖。
第三種:使用靜態同步函式
什麼是靜態同步函式?
同步函式上加上static關鍵字修飾或者使用執行緒類.class檔案位元組碼
public static synchronized void sale() catch (exception e)
system.out.println(thread.currentthread().getname() + "**第" + (100 - traincount + 1) + "張票");
traincount--;}}
再動腦筋思考一下,同步函式使用的是什麼鎖?怎樣證明呢?靜態同步函式使用的鎖是當前執行緒類的位元組碼檔案
證明方式: 乙個執行緒使用當前執行緒類的位元組碼檔案,另乙個執行緒使用靜態同步函式。如果兩個執行緒能實現同步,說明靜態同步函式使用的鎖是當前執行緒類的位元組碼檔案。
什麼是多執行緒死鎖?
同步中巢狀同步,鎖沒有來得及釋放,一直等待,就會導致死鎖。
下面就拿買火車票來演示一下死鎖問題:
class threadtrain implements runnable
}} else }}
/*** @methoddesc: 功能描述:(**火車票)
*/public synchronized void sale() catch (exception e)
system.out.println(thread.currentthread().getname() + "**第" + (100 - traincount + 1) + "張票");
traincount--;}}
}}public class deadlockthread
}//此時執行緒thread1需要執行緒thread2的this鎖,執行緒thread2需要執行緒thread1的obj鎖,互相要鎖,並且互相都不釋放,就會產生死鎖問題。
那麼怎樣可以避免死鎖呢?最好的方法就是不要在同步中巢狀同步 女朋友也能看懂的Zookeeper分布式鎖原理
前言 關於分布式鎖,在網際網路行業的使用場景還是比較多的,比如電商的庫存扣減,秒殺活動,集群定時任務執行等需要程序互斥的場景。而實現分布式鎖的手段也很多,大家比較常見的就是redis跟zookeeper,今天我們主要介紹的是基於zookeeper實現的分布式鎖。這篇文章主要借用curator框架對z...
小白也能看懂的XML簡介
目錄 一.xml簡介 二 xml用途 三 xml結構 四 xml語法 五 xml元素 六 xml屬性 七 總結 1.xml指可擴充套件標記語言,很類似html。xml被設計為傳輸和儲存資料,其焦點是資料的內容 html被設計用來顯示資料,其焦點是資料的外觀。2.xml的設計宗旨是傳輸資料,而非顯示資...
小白也能看懂的Cookie跟Session的區別
首先為了能充分理解為什麼引入cookie和cookie是什麼,先看了例子。不然官網上定義的概念不太容易看懂。eg 我今天想找老王吃放,打 給老王 例子看完了,在看看一些官網上一些專業術語的定義。會話 由一組請求和響應組成 理解為上面例子中的 對話 是圍繞著一件相關事情 吃飯 所進行的請求和響應。這些...