1. 程式人生 > >java中的線程問題是(四)——線程同步問題

java中的線程問題是(四)——線程同步問題

代碼 線程同步 tac int java 檢查 cnblogs 速度 機制

多線程的並發,給我們編程帶來很多好處,完成更多更有效率的程序。但是也給我們帶來線程安全問題。

解決問題的關鍵就是要保證容易出問題的代碼的原子性,所謂原子性就是指:當a線程在執行某段代碼的時候,別的線程必須等到a線程執行完後,它才能執行這段代碼。也就是排隊一個一個解決。

java處理線程兩步的方法非常簡單,只需要在需要同步的代碼段,用:synchronized(Object){你要同步的代碼}即可。

對同步機制的解釋:

java任意類型的對象都有一個標誌位,該標誌位具有0、1兩種狀態,其開始狀態為1,當某個線程執行了synchronized(Object)語句後,object對象的標誌位變為0的狀態,直到執行完整個synchronized語句中的代碼塊後,該對象的標誌位又回到1狀態。

當一個線程執行到synchronized(Object)語句的時候,先檢查Object對象的標誌位,如果為0狀態,表明已經有另外的線程正在執行synchronized包括的代碼,那麽這個線程將暫時阻塞,讓出CPU資源,直到另外的線程執行完相關的同步代碼,並將Object對象的標誌位變為狀態,這個線程的阻塞就被取消,線程能繼續運行,該線程又將Object的標誌位變為0狀態,防止其它的線程再進入相關的同步代碼塊中。

如果有多個線程因等待同一個對象的標誌位面而處於阻塞狀態時,當該對象的標誌位恢復到1狀態時,只會有一個線程能夠進入同步代碼執行,其它的線程仍處於阻塞的狀態。

特別說明:

1、上面所說的標誌位用術語講就是對象鎖,文件鎖。數據庫會有行鎖、表鎖等

2、synchronized(object)//object(就是對象鎖)可以是任意類型對象

3 synchronized也可以修飾方法,當其修飾方法是,對象鎖默認為(this)。

售票系統的演示

 1 /**
 2  * 功能:使用線程的註意事項
 3  * 線程並發同步鎖synchronized(Object){}的使用
 4  */
 5 public class Thread05 {
 6     public static void main(String[] args) {
 7         //定義一個售票窗口
 8         TicketWindow tw1=new TicketWindow();
9 10 //使用三個線程同時啟動 11 Thread t1=new Thread(tw1); 12 Thread t2=new Thread(tw1); 13 Thread t3=new Thread(tw1); 14 15 t1.start(); 16 t2.start(); 17 t3.start(); 18 } 19 } 20 21 //售票窗口類 22 class TicketWindow implements Runnable { 23 //共有2000張票 24 private int nums=2000; 25 private Dog myDog=new Dog(); 26 27 public void run() { 28 while(true){ 29 //出票速度是1秒出一張 30 try { 31 Thread.sleep(1000); 32 } catch (Exception e) { 33 e.printStackTrace(); 34 } 35 36 //認為if else要保證其原子性 37 //先判斷是否還有票 38 synchronized(myDog){//synchronized(this){}為同步代碼塊 39 if(nums>0){ 40 //顯示售票信息 41 //Thread.currentThread().getName()得到當前線程的名字 42 System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"張票"); 43 nums--; 44 }else{ 45 //售票結束 46 break; 47 } 48 } 49 } 50 } 51 }

java中的線程問題是(四)——線程同步問題