【Java併發編程一】線程安全問題

1.多線程的實現

 

多線程有兩種實現方式:安全

1.1.繼承Thread類 =>示例:A a=new A(); a.start();


 

1.2.實現Runnable接口 =>示例:A a=new A(); new Thread(A,自定義線程名稱).start();


 

其實Thread和Runnable都實現了run方法,這種操做模式其實就是代理模式多線程

獲取當前線程名稱:Thread.currentThread().getName()ide

調用線程是thread.start(),真正執行線程是 thread.run()函數

 

具體代碼:this

 1 /**
 2  * 繼承Thread類  3  * @date 2019/3/29 11:19  4  */
 5 public class SimpleThread extends Thread{  6 
 7  @Override  8     public void run() {  9         super.run(); 10         Thread thread = Thread.currentThread(); 11         System.out.println("Thread =>當前執行的線程爲:"+thread.getName()); 12  } 13 } 14 
15 /**
16  * 實現Runnable接口 17  * @date 2019/3/29 11:28 18  */
19 public class SimpleRunnable implements Runnable { 20 
21  @Override 22     public void run() { 23          Thread thread = Thread.currentThread(); 24          System.out.println("Runnable =>當前執行的線程爲:"+thread.getName()); 25  } 26 } 27 
28 public class TestMain { 29 
30 
31     /**執行線程示例1*/
32     private static void callSimpleThread(){ 33         int index=10; 34         for (int i = 0; i < index; i++) { 35              Thread thread=new SimpleThread(); 36  thread.start(); 37  } 38  } 39 
40     /**執行線程示例1*/
41     private static void callSimpleRunnable(){ 42         int index=10; 43         for (int i = 0; i < index; i++) { 44             SimpleRunnable simpleRunnable=new SimpleRunnable(); 45             new Thread(simpleRunnable,"Runnable-"+i).start(); 46  } 47  } 48 
49     public static void main(String[] args) { 50 
51  callSimpleThread(); 52 
53  callSimpleRunnable(); 54  } 55 
56 }

 

 

2.多線程安全問題

 

2.1線程不安全示例

多線程最容易產生的一個問題就是線程安全問題,下面使用一個賣票的例子來體現。
場景描述:如今有兩個售票員,一共賣10張車票
 1 public class SellTicket extends Thread {  2 
 3     private static int NUMBER = 10;  4     public SellTicket(String name) {  5         super(name);  6  }  7 
 8  @Override  9     public void run() { 10         String s = "線程:" + Thread.currentThread().getName(); 11 
12         while (NUMBER > 0) { 13             int i = NUMBER--; 14             System.out.println(s + " => 賣了第" + i + "號票"); 15  } 16 
17         System.out.println(s + ",票已經賣完"); 18         super.run(); 19  } 20 
21 
22     public static void main(String[] args) { 23 
24         SellTicket thread1 = new SellTicket("售票員A"); 25  thread1.start(); 26 
27         SellTicket thread2 = new SellTicket("售票員B"); 28  thread2.start(); 29 
30  } 31 
32 }

執行結果以下:spa

咱們發現售票員A 和售票員B都賣了10號票,這就是線程不安全致使的結果線程

 

 

2.2線程不安全解決方法

方案一:使用同步代碼解決
格式:synchronized(鎖對象){須要被同步的代碼}
鎖對象能夠爲this鎖,也能夠自定義對象鎖

方案二:使用同步函數解決
同步函數就是使用synchronized修飾一個函數

  

下面採用同步代碼塊解決3d

 1 public class SafetySellTicket extends Thread {  2 
 3     private static int NUMBER = 10;  4 
 5  @Override  6     public  void run() {  7         String s = "線程:" + Thread.currentThread().getName();  8 
 9         while (NUMBER > 0) { 10             synchronized (this) { 11                 if (NUMBER > 0) { 12                     int i = NUMBER--; 13                     System.out.println(s + " => 賣了第" + i + "號票"); 14                 } else { 15                     System.out.println(s + ",票已經賣完"); 16                     break; 17  } 18 
19  } 20  } 21         super.run(); 22  } 23 
24 
25     public static void main(String[] args) { 26 
27         SafetySellTicket thread1 = new SafetySellTicket(); 28  thread1.start(); 29 
30         SafetySellTicket thread2 = new SafetySellTicket(); 31  thread2.start(); 32 
33  } 34 
35 }
相關文章
相關標籤/搜索