node.js-認證機制
阿新 • • 發佈:2022-04-18
一.執行緒的安全問題:
1.問題:賣票過程中出現重票和錯票問題(執行緒不安全問題)
2.出現原因:當某個執行緒的操作尚未完成時,其他執行緒的操作就參與進來。(即多個執行緒同時共用一塊資料)
3.解決措施:當一個執行緒在操作共享資料時,其他執行緒不能參與進來(直到原執行緒操作完其他執行緒才可以參與進來)
該情況即使在原執行緒發生了阻塞也不會改變這種情況
4.在Java中通過同步機制來解決執行緒安全問題
二.同步程式碼塊方法:
說明:1.操作共享資料的程式碼,即為需要被同步的程式碼(所包的程式碼不能多也不能少)
2.共享資料:多個執行緒中共同操作的變數(本例即為ticket)
3.同步監視器(鎖):任何一個類的物件都可以作為鎖
要求:多個執行緒必須共同使用同一把鎖(否則無法保證執行緒安全)
補充:可以考慮適用this.class來做鎖
好處:較為簡易的解決了執行緒安全問題。
壞處:將多執行緒轉為單執行緒來解決問題,效率較低
1.同步程式碼塊解決繼承Thread類的執行緒安全問題
程式碼及解析:
1 class Window extends Thread { 2 private static int ticket = 100;//所有同類物件共享static變數 3 4 private static Object obj = new Object();//保證用同一把鎖 5 6 public void run() { 7 while (true) { 8 synchronized (obj) { 9 if (ticket > 0) {10 try { 11 Thread.sleep(1000); 12 } catch (InterruptedException e) { 13 throw new RuntimeException(e); 14 } 15 System.out.println(getName() + "賣票,票號為:" + ticket); 16 ticket--;17 } else { 18 break; 19 } 20 } 21 } 22 } 23 }
2.解決Runnable介面的實現方式的執行緒安全問題:
1 class Window2 implements Runnable { 2 private int ticket = 100; 3 Object obj = new Object(); 4 @Override 5 public void run() { 6 while (true) { 7 //方式一:同步程式碼塊 8 synchronized (obj) { 9 if (ticket > 0) { 10 System.out.println(Thread.currentThread().getName() + "賣票,票號為:" + ticket); 11 ticket--; 12 } else { 13 break; 14 } 15 } 16 } 17 } 18 }
三.同步方法
1.同步方法仍然設計到同步監視器(鎖),但不需要我們顯示宣告
2.靜態方法的鎖為this.class,非靜態方法的鎖為this
1.使用同步方法解決Thread類的繼承問題
1 class Window4 extends Thread { 2 private static int ticket = 100;//所有同類物件共享static變數 3 4 private static Object obj = new Object();//保證用同一把鎖 5 6 public void run() { 7 while (true) { 8 9 } 10 } 11 12 private static synchronized void show() {//使用靜態同步方法實現(靜態保證鎖相同(靜態使鎖設為當前物件的類)) 13 if (ticket > 0) { 14 try { 15 Thread.sleep(100); 16 } catch (InterruptedException e) { 17 throw new RuntimeException(e); 18 } 19 System.out.println(Thread.currentThread().getName() + "賣票,票號為:" + ticket); 20 ticket--; 21 } 22 } 23 }
2.解決Runnable介面的執行緒安全問題:
1 class Window3 implements Runnable { 2 private int ticket = 100; 3 Object obj = new Object(); 4 @Override 5 public void run() { 6 while (ticket > 0) { 7 show(); 8 } 9 } 10 11 public synchronized void show() {//使用同步方法 12 if (ticket > 0) { 13 try { 14 Thread.sleep(1000); 15 } catch (InterruptedException e) { 16 throw new RuntimeException(e); 17 } 18 System.out.println(Thread.currentThread().getName() + "賣票,票號為:" + ticket); 19 ticket--; 20 } 21 } 22 }