1. 程式人生 > >多執行緒案例產生的資料誤差

多執行緒案例產生的資料誤差

xl_echo編輯整理,歡迎轉載,轉載請宣告文章來源。更多IT、程式設計案例、資料請聯絡QQ:1280023003 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!!


需求:一個電影院售票站,總共有四個視窗,但是隻有50張票,如何保證四個視窗售票的同時保證售票不出錯。

分析:售票站就相當於一個程序,在程序當中有個四個執行緒(視窗),所以我們要四個視窗同時執行售票工作,那麼我們的程式就需要四個執行緒。

程式碼示例:

package com.echo;

/**
 * @Author xl_echo
 * @Date 2018/8/7 下午1:54
 **/
public class Window extends Thread { //售票視窗 private final String name; //有50張電影票 private static final int MAXTicket = 50; public Window(String name) { this.name = name; } private int index = 1; @Override public void run(){ while (index <= MAXTicket){ System.out.println("視窗"
+ name + "當前是第" + (index++) + "張票"); } } public static void main(String[] args) { Window window1= new Window("1號視窗"); window1.start(); Window window2= new Window("2號視窗"); window2.start(); Window window3= new Window("3號視窗"); window3.start(); Window window4= new Window("4號視窗"
); window4.start(); } }

根據我們之前的案例,我們需要四個視窗所以我們將Window類集成了Thread,然後每一個window物件,我們呼叫start來啟動一個執行緒。使用四個執行緒執行售票,最後發現並沒有實現我們想要的效果,輸出如下:
這裡寫圖片描述

實際輸出的結果我這裡只截取了一部分,但是也不難發現,有兩個50,其實是每一個執行緒都從1執行到了50。如果對關鍵字掌握熟悉的朋友會發現,我們的index是沒有被static修飾的。當我們的視窗例項化成功時,那麼都會建立一個index,index不是共享資料,所以造成了我們的售票計數出現重複。當我們使用static修飾的時候會出現,index的疊加不會因為執行緒的增加而重複,我們的需求達到了

希望達到我們想要的效果,就要做如下改進

private static int index = 1;

改進後輸出結果如下
這裡寫圖片描述

分析:static是關鍵字,如果用static修飾的變數,將會被共享,在程式被載入的時候就已經創建出來了。

其實通過我們的改進,可以看出我們的輸出結果暫時達到了我們的要求。不過如果我們的資料index增加到很大時,就會出現執行緒安全問題。所以當我們建議最好還是不要使用這種辦法來解決,這裡最好的解決辦法是我們使用Runnable介面來完善這個問題。