什麼是線程安全問題:
當多個線程共享同一個全局變量,並做寫的操作的時候,可能會受到其他線程的干擾,導致數據有問題,這種現象就叫做線程安全問題。
全局變量 與 局部變量,誰會有線程安全問題 ?
全局變量纔會有線程安全問題。在方法內部的局部變量中,每個線程都有自己的局部變量,相互不會干擾。
這裏說全局變量有安全問題,就在說一個面試題(我面試全友傢俬的時候面試官問我的問題):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();
}
}