多線程 多線程是我們開發人員經常提到的一個名詞。為什麼會有多線程的概念呢?我們的電腦有可能會有多個cpu(或者CPU有多個內核)這就產生了多個線程。對於單個CPU來說,由於CPU運算很快,我們在電腦上運行多個軟體時,每個軟體在CPU上運行很短的時間就會切換成其他軟體。由於來回切換的時間很短,我們感覺 ...
多線程
多線程是我們開發人員經常提到的一個名詞。為什麼會有多線程的概念呢?我們的電腦有可能會有多個cpu(或者CPU有多個內核)這就產生了多個線程。對於單個CPU來說,由於CPU運算很快,我們在電腦上運行多個軟體時,每個軟體在CPU上運行很短的時間就會切換成其他軟體。由於來回切換的時間很短,我們感覺好像所有的程式都在同時運行,這也是多線程。多線程可以解決較多的用戶訪問同一個服務時壓力過大的問題,可以更充分的利用電腦的性能。
多線程的問題
多線程的好處很多,可是相應的也出現了一些問題。其中最常見的就是臟讀了。我們的程式,在多個線程訪問同一個共用的數據,並且出現了對數據進行修改的時候,就很有可能出現臟讀的情況。比如說:我有一個用戶名為:yonghu,密碼為:123的數據。我有兩個線程,第一個線程將用戶名密碼修改為:yonghu1 : 456 第二個線程負責將修改後的數據讀取。並且列印。這個時候,就有可能出現這樣的輸出:(用戶名:yonghu 密碼:456)的情況,這就是多線程併發帶來的問題。代碼如下:
1 package jgs_11; 2 3 public class DirtyRead { 4 private String username = "yonghu"; 5 private String password = "123"; 6 // public synchronized void setValue(String username, String password) { 7 public void setValue(String username, String password) { 8 this.username = username; 9 try { 10 Thread.sleep(2000); 11 } catch (Exception e) { 12 e.printStackTrace(); 13 } 14 this.password = password; 15 System.out.println("setValue 最終結果:username =" + username + ", password = " + password); 16 } 17 18 public synchronized void getValue() { 19 System.out.println("getValue 最終結果:username =" + this.username + ", password = " + this.password); 20 } 21 22 public static void main(String[] args) throws Exception { 23 final DirtyRead dr = new DirtyRead(); 24 Thread t1 = new Thread(new Runnable() { 25 @Override 26 public void run() { 27 dr.setValue("yonghu1", "1654"); 28 } 29 }); 30 t1.start(); 31 Thread.sleep(1000); 32 dr.getValue(); 33 } 34 35 }
出現這種情況的原因就是兩個線程的方法,修改了同一個數據導致了資源在被修改的時候產生了我們不想要的結果。這就是臟讀。
synchronized關鍵字
那麼,如何解決這個問題呢?我們可以給這個資源加一個鎖,或者給調用這個資源的方法加一個鎖。在一個線程對它進行修改的時候,將資源鎖住,禁止其他線程訪問。等這個線程操作完成後,才允許其他線程進行操作。這樣做可以避免多個線程同時操作一個資源的時候出現問題的情況,但是會出現一個線程等待另外一個線程的情況。性能肯定會降低。這個鎖的代碼很簡單,就是想鎖住誰就給它前面加個synchronized關鍵字。然後就可以了,但是原理卻是很複雜。
大概是這樣子的:其實synchronized的鎖鎖的都是對象。每個對象都有個類似於標記的東西,當我們執行一段代碼,發現有synchronized關鍵字的時候,線程就去嘗試獲取這個關鍵字的鎖(將這個標記修改下內容)。如果獲取成功了(如果內容為標記值為0那麼將值修改為1,表示獲取鎖成功,如果不為0表示當前鎖處於被占用狀態則獲取鎖失敗),那麼就執行代碼。
關於synchronized鎖的原理,博主瞭解的也不是特別的透徹,希望各位大神多加指導。