當(dāng)前位置:
首頁 >
Android(java)学习笔记10:同步中的死锁问题以及线程通信问题
發(fā)布時間:2023/12/13
37
豆豆
生活随笔
收集整理的這篇文章主要介紹了
Android(java)学习笔记10:同步中的死锁问题以及线程通信问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1. 同步弊端:
(1)效率低
(2)如果出現(xiàn)了同步嵌套,就容易產(chǎn)生死鎖問題
死鎖問題及其代碼 :
(1)是指兩個或者兩個以上的線程在執(zhí)行的過程中,因爭奪資源產(chǎn)生的一種互相等待現(xiàn)象
(2)同步代碼塊的嵌套案例
1 package cn.itcast_02; 2 3 public class MyLock { 4 // 創(chuàng)建兩把鎖對象 5 public static final Object objA = new Object(); 6 public static final Object objB = new Object(); 7 } 1 package cn.itcast_02; 2 3 public class DieLock extends Thread { 4 5 private boolean flag; 6 7 public DieLock(boolean flag) { 8 this.flag = flag; 9 } 10 11 @Override 12 public void run() { 13 if (flag) { 14 synchronized (MyLock.objA) { 15 System.out.println("if objA"); 16 synchronized (MyLock.objB) { 17 System.out.println("if objB"); 18 } 19 } 20 } else { 21 synchronized (MyLock.objB) { 22 System.out.println("else objB"); 23 synchronized (MyLock.objA) { 24 System.out.println("else objA"); 25 } 26 } 27 } 28 } 29 } 1 package cn.itcast_02; 2 3 /* 4 * 同步的弊端: 5 * A:效率低 6 * B:容易產(chǎn)生死鎖 7 * 8 * 死鎖: 9 * 兩個或兩個以上的線程在爭奪資源的過程中,發(fā)生的一種相互等待的現(xiàn)象。 10 * 11 * 舉例: 12 * 中國人,美國人吃飯案例。 13 * 正常情況: 14 * 中國人:筷子兩支 15 * 美國人:刀和叉 16 * 現(xiàn)在: 17 * 中國人:筷子1支,刀一把 18 * 美國人:筷子1支,叉一把 19 */ 20 public class DieLockDemo { 21 public static void main(String[] args) { 22 DieLock dl1 = new DieLock(true); 23 DieLock dl2 = new DieLock(false); 24 25 dl1.start(); 26 dl2.start(); 27 } 28 }我們執(zhí)行的時候會發(fā)現(xiàn)程序會鎖住(當(dāng)然這個只是很大幾率會鎖住):如下圖
這里死鎖我們該怎么解決呢?這里引出了線程之間通信:
?
不同種類的線程針對同一個資源的操作
?
?
?
?
2. 下面設(shè)置線程(生產(chǎn)者)和獲取線程(消費(fèi)者)針對同一個學(xué)生對象進(jìn)行操作示例:
代碼實(shí)現(xiàn):
1 package cn.itcast_03; 2 3 /* 4 * 分析: 5 * 資源類:Student 6 * 設(shè)置學(xué)生數(shù)據(jù):SetThread(生產(chǎn)者) 7 * 獲取學(xué)生數(shù)據(jù):GetThread(消費(fèi)者) 8 * 測試類:StudentDemo 9 * 10 * 問題1:按照思路寫代碼,發(fā)現(xiàn)數(shù)據(jù)每次都是:null---0 11 * 原因:我們在每個線程中都創(chuàng)建了新的資源,而我們要求的時候設(shè)置和獲取線程的資源應(yīng)該是同一個 12 * 如何實(shí)現(xiàn)呢?這里是共享資源一種思路 13 * 在外界把這個數(shù)據(jù)創(chuàng)建出來,通過構(gòu)造方法傳遞給其他的類。 14 * 15 */ 16 public class StudentDemo { 17 public static void main(String[] args) { 18 //創(chuàng)建資源----外界創(chuàng)建出資源 19 Student s = new Student(); 20 21 //設(shè)置和獲取的類(這兩個線程類被剛剛創(chuàng)建的資源綁定) 22 SetThread st = new SetThread(s);//通過構(gòu)造方法傳遞給其他類 23 GetThread gt = new GetThread(s);//通過構(gòu)造方法傳遞給其他類 24 25 //線程類 26 Thread t1 = new Thread(st); 27 Thread t2 = new Thread(gt); 28 29 //啟動線程 30 t1.start(); 31 t2.start(); 32 } 33 }?
1 package cn.itcast_03; 2 3 public class SetThread implements Runnable { 4 5 private Student s; 6 7 public SetThread(Student s) { 8 this.s = s; 9 } 10 11 @Override 12 public void run() { 13 // Student s = new Student(); 14 s.name = "林青霞"; 15 s.age = 27; 16 } 17 18 }?
1 package cn.itcast_03; 2 3 public class GetThread implements Runnable { 4 private Student s; 5 6 public GetThread(Student s) { 7 this.s = s; 8 } 9 10 @Override 11 public void run() { 12 // Student s = new Student();//上面SetThread()類中run()方法也出現(xiàn)Student s = new Student(),這樣就出現(xiàn)兩個不同的對象 13 System.out.println(s.name + "---" + s.age); 14 } 15 16 }?
1 package cn.itcast_03; 2 3 public class Student { 4 String name; 5 int age; 6 }上面代碼是有問題的,如下:
?
進(jìn)一步改進(jìn)上面代碼:
1 package cn.itcast_04; 2 3 /* 4 * 分析: 5 * 資源類:Student 6 * 設(shè)置學(xué)生數(shù)據(jù):SetThread(生產(chǎn)者) 7 * 獲取學(xué)生數(shù)據(jù):GetThread(消費(fèi)者) 8 * 測試類:StudentDemo 9 * 10 * 問題1:按照思路寫代碼,發(fā)現(xiàn)數(shù)據(jù)每次都是:null---0 11 * 原因:我們在每個線程中都創(chuàng)建了新的資源,而我們要求的時候設(shè)置和獲取線程的資源應(yīng)該是同一個 12 * 如何實(shí)現(xiàn)呢? 13 * 在外界把這個數(shù)據(jù)創(chuàng)建出來,通過構(gòu)造方法傳遞給其他的類。 14 * 15 * 問題2:為了數(shù)據(jù)的效果好一些,我加入了循環(huán)和判斷,給出不同的值,這個時候產(chǎn)生了新的問題 16 * A:同一個數(shù)據(jù)出現(xiàn)多次 17 * B:姓名和年齡不匹配 18 * 原因: 19 * A:同一個數(shù)據(jù)出現(xiàn)多次 20 * CPU的一點(diǎn)點(diǎn)時間片的執(zhí)行權(quán),就足夠你執(zhí)行很多次。 21 * B:姓名和年齡不匹配 22 * 線程運(yùn)行的隨機(jī)性 23 * 線程安全問題: 24 * A:是否是多線程環(huán)境 是 25 * B:是否有共享數(shù)據(jù) 是 26 * C:是否有多條語句操作共享數(shù)據(jù) 是 27 * 解決方案: 28 * 加鎖。 29 * 注意: 30 * A:不同種類的線程都要加鎖。 31 * B:不同種類的線程加的鎖必須是同一把。 32 */ 33 public class StudentDemo { 34 public static void main(String[] args) { 35 //創(chuàng)建資源 36 Student s = new Student(); 37 38 //設(shè)置和獲取的類 39 SetThread st = new SetThread(s); 40 GetThread gt = new GetThread(s); 41 42 //線程類 43 Thread t1 = new Thread(st); 44 Thread t2 = new Thread(gt); 45 46 //啟動線程 47 t1.start(); 48 t2.start(); 49 } 50 }?
1 package cn.itcast_04; 2 3 public class SetThread implements Runnable { 4 5 private Student s; 6 private int x = 0; 7 8 public SetThread(Student s) { 9 this.s = s; 10 } 11 12 @Override 13 public void run() { 14 while (true) { 15 synchronized (s) { 16 if (x % 2 == 0) { 17 s.name = "林青霞";//剛走到這里,就被別人搶到了執(zhí)行權(quán) 18 s.age = 27; 19 } else { 20 s.name = "劉意"; //剛走到這里,就被別人搶到了執(zhí)行權(quán) 21 s.age = 30; 22 } 23 x++; 24 } 25 } 26 } 27 }?
1 package cn.itcast_04; 2 3 public class GetThread implements Runnable { 4 private Student s; 5 6 public GetThread(Student s) { 7 this.s = s; 8 } 9 10 @Override 11 public void run() { 12 while (true) { 13 synchronized (s) { 14 System.out.println(s.name + "---" + s.age); 15 } 16 } 17 } 18 }?
1 package cn.itcast_04; 2 3 public class Student { 4 String name; 5 int age; 6 }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/hebao0514/p/4509803.html
總結(jié)
以上是生活随笔為你收集整理的Android(java)学习笔记10:同步中的死锁问题以及线程通信问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分期乐还信用卡要审核吗?怎么解决?
- 下一篇: [置顶] Android开发者官方网站文