Java基礎-多線程-②多線程安全問題


什么是線程的安全問題?

上一篇 Java基礎-多線程-①線程的創建和啟動 我們說使用實現Runnable接口的方式來創建線程,可以實現多個線程共享資源:

 1 class Dog implements Runnable {
 2     // 定義線程共享數據
 3     private int t = 100;
 4 
 5     @Override
 6     public void run() {
 7         // TODO:死循環,暫不處理
 8         while (true) {
 9             if (t > 0) {
10 
11                 System.out.println("當前線程:" + Thread.currentThread().getName() + "---" + t--);
12             }
13         }
14     }
15 }
16 
17 public class ThreadDemo {
18     public static void main(String[] args) {
19         System.out.println("當前線程:" + Thread.currentThread().getName());
20         Dog dog = new Dog();
21 
22         Thread thread = new Thread(dog);
23         Thread thread2 = new Thread(dog);
24         thread.start();
25         thread2.start();
26 
27     }
28 }

開啟兩個線程,共享數據t=100,執行run方法中的代碼:當t大於0時,打印t--。分析一下可能會存在的問題:

因為CPU時間片快速切換的不確定性,該問題不一定會發生,為了模擬一下該問題的發生,在打印語句執行前,讓線程睡眠0.1秒:

 1 @Override                                                                                              
 2 public void run() {                                                                                    
 3     while (true) {                                                                                     
 4         if (t > 0) {                                                                                   
 5             try {                                                                                      
 6                 Thread.sleep(100);                                                                     
 7                 System.out.println("當前線程:" + Thread.currentThread().getName() + "---" + t--);          
 8             } catch (InterruptedException e) {                                                         
 9                 //TODO:暫不處理異常                                                                          
10             }                                                                                          
11         }                                                                                              
12     }                                                                                                  
13 }                                                                                                      

 

問題產生的原因

首先我們想到是因為兩個線程共享了數據t。如果多個線程不涉及數據共享,各自執行自己的代碼,就不會出現這個問題。在線程不安全的單例模式中,就涉及到這個問題。

①多個線程共享了數據。

如果我們不判斷t>0,直接打印t--,或者只判斷t>0,不執行t--,只要循環不結束,程序不終止,從邏輯上來說,程序也沒有問題

②在線程任務中設計對共享數據的操作(這里的操作包括①判斷t>0;②執行t--),一個線程在操作共享數據的時候,其他的線程也操作了共享數據。

這時候就可能造成數據出錯。

總結來說,多個線程在執行同一段代碼的時候,每次的執行結果和單線程執行的結果都是一樣的,不存在執行結果的二義性,就可以稱作是線程安全的。線程安全問題多是由全局變量和靜態變量引起的,當多個線程對共享數據只執行讀操作,不執行寫操作時,一般是線程安全的;當多個線程都執行寫操作時,需要考慮線程同步來解決線程安全問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM