多線程講解四: 線程安全問題 (全局變量 與 局部變量,誰會有線程安全問題 ?)

 

什麼是線程安全問題:

當多個線程共享同一個全局變量,並做寫的操作的時候,可能會受到其他線程的干擾,導致數據有問題,這種現象就叫做線程安全問題。

 

全局變量 與 局部變量,誰會有線程安全問題 ?

全局變量纔會有線程安全問題。在方法內部的局部變量中,每個線程都有自己的局部變量,相互不會干擾。

 

這裏說全局變量有安全問題,就在說一個面試題(我面試全友傢俬的時候面試官問我的問題):String ,StringBuffer,StringBuilder 什麼時候使用他們 ?

首先,String是每個String類型的變量都會存儲在常量池中,且不會被回收,所以用String對性能有所影響。

StringBuffer 和 StringBuilder是對象,可以被GC回收。

StringBuffer是線程安全的,但是效率低,所以如果是定義全局變量使用StringBuffer。

但是由於方法內部定義變量,沒有線程安全問題,也就是說,方法內部的變量線程全都是安全的,所有在方法內部定義變量,最好使用線程不安全的StringBuilder。

 

 

public class CountThread implements Runnable {


    /**
     * 需求現在有10張火車票,有兩個窗口同時搶火車票,請使用多線程模擬搶票效果。
     * <p>
     * 下面的寫法有線程安全問題,原因就是多個線程共享了同一個全局變量。
     */
    private int count = 10;

    public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while (count > 0) {
            System.out.println(Thread.currentThread().getName() + ",出售第" + (10 - count + 1) + "票");
            count--;
        }

    }
}
public class Test {


    /**
     * 結果:
     * <p>
     * 線程2,出售第1票
     * 線程2,出售第2票
     * 線程1,出售第1票
     * 線程1,出售第4票
     * 線程1,出售第5票
     * 線程1,出售第6票
     * 線程2,出售第3票
     * 線程1,出售第7票
     * 線程2,出售第8票
     * 線程1,出售第9票
     * 線程2,出售第10票
     * <p>
     * 因爲多個線程同時寫操作了同一個 全局變量,所有出現了線程安全問題。
     */
    public static void main(String[] args) {

        CountThread c1 = new CountThread();
        CountThread c2 = new CountThread();

        Thread thread1 = new Thread(c1, "線程1");
        Thread thread2 = new Thread(c1, "線程2");

        thread1.start();
        thread2.start();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章