1. 程式人生 > >執行緒安全問題:同步程式碼塊synchronized

執行緒安全問題:同步程式碼塊synchronized

package thread;

public class ThreadDemo4 {

 /**
  * @執行緒安全問題:
  * 通過分析,發現,打印出0,-1,-2等錯票。
  * 多執行緒的執行出現了安全問題。
  *
  *  問題的原因:
  *   當多條語句在操作同一個執行緒共享資料時,一個執行緒對多條語句只執行了一部分,還沒有執行完,
  *   另一個執行緒就參與進來執行,導致了共享資料的錯誤。
  *  解決辦法:
  *   對多條操作共享資料的語句,只能讓一個執行緒都執行完,在執行過程中,其他執行緒不可以參與執行。
  * 
  *  Java對多執行緒的安全問題提供了專業的解決方式。
  * 
  *  就是同步程式碼塊。
  * 
  *  synchronized(物件)
  *  {
  *   需要被同步的程式碼
  *  }
  * 
  *  物件如同鎖,持有鎖的執行緒可以在同步中執行,
  *  沒有持有鎖的執行緒即使獲取cpu的執行權,也進不去,因為沒有獲取鎖。
  * 
  *  同步的前提:
  *  1,必須要有兩個或者兩個以上的執行緒。
  *  2,必須是多個執行緒使用同一個鎖。
  * 
  *  必須保證同步中只能有一個執行緒在執行。
  * 
  *  好處:解決了多執行緒的安全問題。
  *  弊端:多個執行緒需要判斷鎖,較為消耗資源。
  *
  */
 public static void main(String[] args) {
  /*繼承Thread的run方法的呼叫
  Ticket t1 = new Ticket();
  Ticket t2 = new Ticket();
  Ticket t3 = new Ticket();
  Ticket t4 = new Ticket();
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  */
  
  //實現Runnable介面
  
  Ticket1 t = new Ticket1();
  Thread t1 = new Thread(t);//建立了一個執行緒
  Thread t2 = new Thread(t);//建立了一個執行緒
  Thread t3 = new Thread(t);//建立了一個執行緒
  Thread t4 = new Thread(t);//建立了一個執行緒
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  
  
 }

}

class Ticket1 implements Runnable//extends Thread
{
 
 private int tick = 100;
 Object obj = new Object();
 public void run()
 {
  while(true){
   synchronized(obj){
   if(tick>0){
    try {
     Thread.sleep(10);
    } catch (InterruptedException e)
    {
     //e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sale : "+ tick--);
   }
   }
  }
 }
}