實體探索多執行緒安全問題
- 1.利用繼承Thread類的方式賣電影票
- 2.實作Runnable介面的方式賣電影票
- 3.執行緒安全問題的實體發生
- 4.分析多執行緒安全問題的產生原因
- 總結
臨近春節,各大電影院都在籌備準備上映賀歲大片,假設某家電影院持有唐探3的票100張,而且它總共有三個售票視窗,請設計一個程式模擬該電影院進行售票,
1.利用繼承Thread類的方式賣電影票
| 事件具體分析 |
|---|
| 1.三個視窗其實就是三個執行緒 |
| 2.定義票的數量為100張(為靜態變數,被3個執行緒所共享 |
| 3.創建執行緒物件,啟動執行緒,每賣一張票,票的數量就減1 |
public class CellThread extends Thread {
//定義一個靜態常量被3個執行緒所共享
static int piao=100;
@Override
public void run() {
while (true) {
if (piao > 0) {
System.out.println(this.getName() + "搶到了第" + (piao--) + "票");
}
}
}
}
public class MyTest {
public static void main(String[] args) {
/* A:
案例演示
需求:某電影院目前正在上映賀歲大片,共有100張票,而它有3個售票視窗售票,請設計一個程式模擬該電影院售票,
通過繼承Thread類實作*/
//100張票 屬于共享資源,三個視窗共同賣
//三個視窗就相當于三個執行緒,
CellThread th1 = new CellThread("視窗1");
CellThread th2 = new CellThread("視窗2");
CellThread th3 = new CellThread("視窗3");
th1.start();
th2.start();
th3.start();
}
}
三個執行緒共享100張票,且搶票是通過執行緒并發形式去進行的,
2.實作Runnable介面的方式賣電影票
public class CellRunnable implements Runnable {
//定義公共的靜態常量,即為共享變數
static int piao=100;
private String name;
public CellRunnable() {
}
@Override
public void run() {
while(true){
if(piao>0)
System.out.println(Thread.currentThread().getName()+"搶到第"+(piao--)+"張票");
}
}
}
public class MyTest2 {
public static void main(String[] args) {
/* 需求:某電影院目前正在上映賀歲大片,共有100張票,而它有3個售票視窗售票,請設計一個程式模擬該電影院售票,
通過實作Runnable介面實作*/
//100張票 屬于共享資源,三個視窗共同賣
//三個視窗就相當于三個執行緒,
CellRunnable myRunnable= new CellRunnable();
Thread th1 = new Thread(myRunnable,"視窗1");
Thread th2 = new Thread(myRunnable,"視窗2");
Thread th3 = new Thread(myRunnable,"視窗3");
th1.start();
th2.start();
th3.start();
}
}
3.執行緒安全問題的實體發生
我們前面已經說過電影院的售票程式,從表面上看不出存在什么問題,但在真實生活中,售票時網路不是實時傳輸的,總是存在延遲的情況,所以需要一點點時間的延遲,我們可以通過改實作介面的賣票程式,每次延遲100ms,進行模擬網路延遲,設定后買電影票就會發生同票與零票的情況發生,(即發生所謂的執行緒安全問題)
public class CellRunnable implements Runnable {
//將票數設定為靜態常量,即為共享變數
static int piao=100;
@Override
public void run() {
while(true){
try {
//模擬網路演延遲
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(piao>0){
System.out.println(Thread.currentThread().getName()+"搶到了第"+(piao--)+"張票");
}
}
public class MyTest {
public static void main(String[] args) {
/*
* 我們模擬了一下,網路售票延遲,就出現了一些不合理的資料,也就是說,出現了執行緒安全問題,
* 1.出現了0票 同票,這是由于執行緒的隨機性導致,并發導致的,
* 2.出現了重復票,原因是由于,原子性所導致的,原子性:不可再分割性
* piao-- 它不是一個原子性的操作,
* piao-- 要經過三個步驟 讀 改 寫
* */
CellRunnable cellRunnable = new CellRunnable();
Thread th1 = new Thread(cellRunnable,"視窗1");
Thread th2 = new Thread(cellRunnable,"視窗2");
Thread th3 = new Thread(cellRunnable, "視窗3");
th1.start();
th2.start();
th3.start();
}
}
出現了同票、零票與負票的現象:

4.分析多執行緒安全問題的產生原因
通常判斷一個多執行緒應用程式是否有問題的標準:
- 1.是否是多執行緒環境
- 2.是否存在共享資料
- 3.是否存在多條陳述句同時操作共享資料
上面的賣票程式是存在問題的,因為它滿足上面的標準,才會引起多執行緒的安全問題,那么我們就可以解決這個問題,而上面的標準中是否存在多執行緒環境與是否存在共享資料是不能打亂的,因此我們對是否存在多條陳述句同時操作共享資料可以進行處理,
處理的思路為:我們將操作共享資料的多條陳述句看作成一個整體,當一個執行緒執行這個整體時,其他的執行緒處于等待的狀態,也就是說當一個執行緒執行這個整體的時候,其他執行緒不能執行,
總結
對于執行緒的安全性的實體以及產生原因已經介紹給大家了,下次給大家介紹具體解決執行緒安全問題的方案,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/254030.html
標籤:其他
上一篇:如何免費給域名申請SSL證書,并配置到相關網站上,讓自己的小網站也能擁有HTTPS連接方式
下一篇:資訊安全實驗——點擊劫持技術
