国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

多線程--畢向東java基礎教程視頻學習筆記

2019-11-14 14:58:05
字體:
來源:轉載
供稿:網友

目錄

1.多線程運行的安全問題

2.多線程同步代碼塊

3.同步方法的鎖是this

4.靜態同步方法的鎖是Class對象

5.單例設計模式(面試中的考點)

6.死鎖(一個發生死鎖的例子)

 

多線程運行的安全問題

例子:售票系統

 1 class Ticket implements Runnable 2 { 3     //定義靜態變量ticket 4     PRivate static int ticket=100; 5     public void run() 6     { 7         while(true) 8         { 9             //判斷票編號是否大于010             if(ticket>0)11             {12                 try13                 {14                     Thread.sleep(10);15                 }16                 catch (InterruptedException ie)17                 {18                     System.err.println("Error:"+ie);19                 }20                 System.out.println(Thread.currentThread().getName()+"--sale:"+ticket--);21             }22         }23     }24 25 }26 public class ThreadDemo27 {28     29     public static void main(String[] args)30     {31         //創建一個實現了Runnable接口的Ticket對象32         Ticket t=new Ticket();33         //創建4個線程34         Thread t1=new Thread(t);35         Thread t2=new Thread(t);36         Thread t3=new Thread(t);37         Thread t4=new Thread(t);38         //分別啟動4個線程39         t1.start();40         t2.start();41         t3.start();42         t4.start();43 44     }45 }

運行:

最后,打印出了了“0,-1,-2”的錯票情況(票的編號從1-100).多線程出現安全問題。

 

問題的原因:

當多條語句在操作用一個線程共享數據時,一個線程對多條語句只執行了一部分,還沒執行完,

另一個數據參與進來執行,造成共享數據的錯誤。

解決方法:

對多條操作共享數據的語句,只能讓一個線程都執行完,在執行過程中不允許其他線程參與進來。

java對于多線程的同步提供了專業的解決方法,就是同步代碼塊。

 

多線程同步代碼塊

synchronized(對象)

{需要被同步的代碼塊}

對象如同鎖,持有鎖的線程可以在同步代碼塊中執行,

沒有持有鎖的線程即使獲得CPU的執行權也進不去,因為沒有獲取鎖。

 

例子:火車上的衛生間。

同步的前提:

1.必須要有兩個或者兩個以上的線程。

2.必須是多個線程使用同一把鎖。

 

好處:解決了多線程的安全問題。

弊端:需要判斷鎖,較為消耗資源。

 一般不可以把run()方法全放在同步代碼塊中,否則就是單線程了。

 

同步方法:

銀行
有兩個儲戶,分別存300元,每次存100元,存3次
目的:該線程是否有安全問題,如果有,如何解決?

如何找問題:
1.明確哪些代碼是多線程運行代碼
2.明確共享數據
3.明確多線程運行代碼中哪些代碼操作共享數據的。

 1 class Bank 2 { 3     //定義sum,代表銀行的總金額 4     private int sum; 5     Object obj=new Object(); 6     public void add(int n) 7     { 8          9         //sum為共享數據,對sum有兩句操作,10         //防止出現不安全問題,使用同步代碼塊11         synchronized(obj)12         {13             sum=sum+n;14             try15             {16                 Thread.sleep(10);17             }18             catch (InterruptedException ie)19             {20                 System.err.println("Error:"+ie);21             }22             System.out.println("sum="+sum);23         }24     }25 }26 class Cus implements Runnable27 {28     private Bank b=new Bank();29     //存三次30     public void run()31     {32         for(int i=0;i<3;i++)33             b.add(100);34     }35 }36 public class BankDemo37 {38     public static void main(String[] args)39     {40         Cus cus=new Cus();41         //創建兩個線程,代表2個儲戶的存錢過程42         Thread t1=new Thread(cus);43         Thread t2=new Thread(cus);44         t1.start();45         t2.start();46     }47 }

注:同步的兩種表現形式:a.同步代碼塊   b.同步函數

 

同步方法的鎖是this

同步方法用的是哪一個鎖呢?

方法需要被對象調用,那么方法都有一個所屬對象的引用,就是this。

所以同步方法的鎖就是this。

 

靜態同步方法的鎖是Class對象

當同步方法被靜態修飾后,使用的鎖就不是this了,因為靜態方法中不可以使用this。

靜態方法進內存時,內存沒有本類對象,但一定有該類對應的字節碼文件對象。

類名.class。該對象的類型是Class。

靜態同步方法,使用的鎖是該方法所在的類的字節碼文件對象。類名.class

 

單例設計模式

1.餓漢式

1 class Single2 {3     private static final Single s=new Single();4     private Single(){}5     public static Single getInstance()6     {7         return s;8     }9 }

2.懶漢式:

 1 /* 2 面試時的考點: 3  4 懶漢式的特點:實例的延遲加載 5 會出現的問題:多線程訪問時會出現安全問題 6 解決方法:用同步方法或者同步代碼塊都行, 7 但是有些低效,可以通過雙重判斷,減少判斷鎖的次數,稍微提高效率。 8 加同步時候:使用的鎖是該類的字節碼對象 9 10 */11 class Single12 {13     private static  Single s=null;14     private Single(){}15     public static Single getInstance()16     {17         //通過雙重判斷,減少判斷鎖的次數,稍微提高效率。18         if (s==null)19         {20             synchronized (Single.class)21             {22                 if(s==null)23                     s=new Single();24             }25         }26         return s;27     }28 }

 

死鎖:同步中嵌套同步

死鎖的例子

 1 class Test implements Runnable 2 { 3     private boolean flag; 4     Test(boolean _flag) 5     { 6         flag=_flag; 7     } 8     public void run() 9     {10         if(flag)11         {12             synchronized(MyLock.locka)13             {14                 System.out.println("if locka");15                 synchronized(MyLock.lockb)16              {17                     System.out.println("if lockb");18 19              }20 21             }22 23         }24         else25         {26             synchronized(MyLock.lockb)27             {28                 System.out.println("else lockb");29                 synchronized(MyLock.locka)30              {31                     System.out.println("else locka");32 33              }34 35             }36 37         }38 39     }40 }41 class MyLock42 {43     static Object locka=new Object();44     static Object lockb=new Object();45 }46 public class DeadLockTest47 {48     public static void main(String[] args)49     {50         Thread t1=new Thread(new Test(true));51         Thread t2=new Thread(new Test(false));52         t1.start();53         t2.start();54 55     }56     57 }

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 抚远县| 舞钢市| 古浪县| 普陀区| 邵阳县| 曲周县| 雅江县| 衢州市| 屏东市| 神池县| 永泰县| 安溪县| 盐亭县| 龙川县| 邵阳县| 黑龙江省| 泰宁县| 左权县| 沾化县| 唐河县| 甘谷县| 来安县| 娱乐| 蚌埠市| 新竹县| 漳州市| 潢川县| 枣庄市| 南澳县| 平利县| 教育| 万山特区| 韩城市| 孟州市| 吉安县| 毕节市| 富川| 晋宁县| 天峻县| 阳原县| 五大连池市|