JavaSE-20.2.2【執行緒同步:同步程式碼塊、同步方法解決資料安全問題(賣票案例問題解決)】
阿新 • • 發佈:2021-06-10
1 package day11.lesson2; 2 3 /* 4 2.3 同步程式碼塊解決資料安全問題(賣票案例問題解決) 5 6 賣票案例為啥會出現問題?(多執行緒程式出現安全問題的標準條件) 7 是多執行緒環境 8 有共享資料 9 有多條語句操作共享資料 10 11 如何解決多執行緒安全問題呢? 12 基本思想:讓程式沒有安全問題的環境,即至少破壞掉上述其中一個條件 13 14 怎麼實現呢? 15 把多條語句操作共享資料的程式碼給鎖起來,讓任意時刻只能有一個執行緒執行即可16 Java提供了同步程式碼塊的方式來解決 17 18 同步程式碼塊格式: 19 synchronized(任意物件) { 20 多條語句操作共享資料的程式碼 21 } 22 synchronized(任意物件):就相當於給程式碼加鎖了,任意物件就可以看成是一把鎖 23 24 同步的好處和弊端 25 好處:解決了多執行緒的資料安全問題 26 弊端:當執行緒很多時,因為每個執行緒都會去判斷同步上的鎖,這是很耗費資源的,無形中會降低程式的執行效率 27 28*/ 29 public class SellTicket2 implements Runnable{ 30 31 private int tickets = 100; 32 private Object obj = new Object(); 33 34 @Override 35 public void run() { 36 while (true){ 37 synchronized (obj){ 38 if(tickets > 0){ 39 try{ 40 Thread.sleep(100); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票"); 45 tickets--; 46 } 47 } 48 } 49 } 50 } 51 52 class SellTicketDemo2{ 53 public static void main(String[] args) { 54 SellTicket2 st = new SellTicket2(); 55 56 Thread t1 = new Thread(st, "視窗1"); 57 Thread t2 = new Thread(st, "視窗2"); 58 Thread t3 = new Thread(st, "視窗3"); 59 60 t1.start(); 61 t2.start(); 62 t3.start(); 63 } 64 }
1 package day11.lesson2; 2 3 /* 4 2.4 同步方法解決資料安全問題 5 6 同步方法 7 同步方法:就是把synchronized關鍵字加到方法上 8 修飾符 synchronized 返回值型別 方法名(方法引數) { 9 方法體; 10 } 11 同步方法的鎖物件是什麼呢? 12 this 13 14 靜態同步方法 15 同步靜態方法:就是把synchronized關鍵字加到靜態方法上 16 修飾符 static synchronized 返回值型別 方法名(方法引數) { 17 方法體; 18 } 19 同步靜態方法的鎖物件是什麼呢? 20 類名.class 21 */ 22 public class SellTicket3 implements Runnable{ 23 24 // private int tickets = 100; 25 private static int tickets = 100; 26 private Object obj = new Object(); 27 private int x = 0; 28 29 @Override 30 public void run() { 31 while (true){ 32 if(x % 2 == 0){ 33 // synchronized (obj){ 34 // synchronized (this){ 35 synchronized (SellTicket.class){ 36 if(tickets > 0){ 37 try { 38 Thread.sleep(100); 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } 42 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票"); 43 tickets--; 44 } 45 } 46 }else { 47 /*synchronized (obj){ 48 if(tickets > 0){ 49 try { 50 Thread.sleep(100); 51 } catch (InterruptedException e) { 52 e.printStackTrace(); 53 } 54 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票"); 55 tickets--; 56 } 57 }*/ 58 sellTickets(); 59 } 60 x++; 61 } 62 } 63 64 /*private void sellTickets() { 65 synchronized (obj){ 66 if(tickets > 0){ 67 try { 68 Thread.sleep(100); 69 } catch (InterruptedException e) { 70 e.printStackTrace(); 71 } 72 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票"); 73 tickets--; 74 } 75 } 76 }*/ 77 78 private static synchronized void sellTickets() { //靜態同步方法 79 if(tickets > 0){ 80 try { 81 Thread.sleep(100); 82 } catch (InterruptedException e) { 83 e.printStackTrace(); 84 } 85 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票"); 86 tickets--; 87 } 88 } 89 90 } 91 92 93 class SellTicketDemo3{ 94 public static void main(String[] args) { 95 SellTicket3 st = new SellTicket3(); 96 97 Thread t1 = new Thread(st, "視窗1"); 98 Thread t2 = new Thread(st, "視窗2"); 99 Thread t3 = new Thread(st, "視窗3"); 100 101 t1.start(); 102 t2.start(); 103 t3.start(); 104 } 105 }