1. 程式人生 > >多線程安全問題

多線程安全問題

-- pack ati rac alt args 是否 實現類 發生

多線程訪問共享數據會產生安全問題,比如下面的案例,創建了三個線程,訪問共享的數據,會出現安全問題

Runable實現類

當ticket的值大於0,run方法裏輸出ticket的值

package cn.zhuobo.day12.aboutMultithreading;

public class RunableImpl implements Runnable {
    private int ticket = 100;
    @Override
    public void run() {
        while(true) {
            if(ticket > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " is selling ticket number--> " + ticket);
                ticket--;
            }
        }
    }
}

創建多個線程

創建一個Runable實現類的對象,用這個對象構造三個Thread對象,開啟三個線程,這三個線程是共同訪問共享數據ticket的,根據結果發現出現線程安全問題。三個線程一起搶奪CPU的執行權,當某個線程的到CPU,執行run方法,但是僅僅值執行到了某個語句就失去了執行權,也即是任何一個線程在訪問共享數據的時候都有可能發生線程切換,再切換回來時,就會得到錯誤數據。比如0號線程應該得到的ticket值是88,但是,在得到這個數據之前CPU切換了進程,另一個進程將共享數據ticket改變了變成了87,那麽0號線程就得到了錯誤的數據。

package cn.zhuobo.day12.aboutMultithreading;

public class RunableDemo {
    public static void main(String[] args) {
        RunableImpl run = new RunableImpl();
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        Thread t3 = new Thread(run);

        t1.start();
        t2.start();
        t3.start();
    }
}

執行的結果,多個線程會輸出同一個數值

技術分享圖片
這種線程安全問題應該得到解決,可以通過讓一個線程在訪問共享數據的時候,無論CPU是否切換線程都要保證在訪問期間不讓其他線程訪問共享數據,等待該線程訪問完畢其他線程才可以訪問這個共享數據

多線程安全問題