第37節:多線程安全問題

来源:https://www.cnblogs.com/dashucoding/archive/2018/09/04/9582212.html
-Advertisement-
Play Games

定義用戶去銀行存錢,每次存100,存3次 餓漢式 懶漢式 多線程 在同一時間,做多件事情. 創建線程的方法 繼承類Thread並重寫run(),run()稱為線程體;用這種方法定義的類不能再繼承其他類。 class FirstThread extends Thread{ public void ru ...


標題圖

定義用戶去銀行存錢,每次存100,存3次

class Bank {
 // 總數
 private int sum;
// 定義方法
 public void add(int num){
  // 傳入參數
  sum = sum + sum;
 // 加後的值
  System.out.println("sum"+sum);
 }
}

class Demo implements Runnable{
 // 定義銀行類對象,創建實例對象
 private Bank  b = new Bank();
// 線程run()
 public void run(){
  for(int x=0; x<3; x++){
   // 將參數放入對象方法中
   b.add(100)
  }
 }
}

// 測試類
class Test{
 public static void main(String[] args){h
  // 創建對象
  Demo d=new Demo();
 // 創建線程對象
  Thread t1 = new Thread(d);
  Thread t2 = new Thread(d);
 // 線程開啟
  t1.start();
  t2.start();
}
}

如果出現這個代碼,出現了多線程安全問題。共性數據即共用對象中的數據。

class Bank {
 // 總數
 private int sum;
// 創建對象
 private Object obj = new Object();
// 定義方法
 public void add(int num){
  synchronized(obj){
  // 傳入參數
  sum = sum + sum;
 // 加後的值
  System.out.println("sum"+sum);
 }
 }
}

安全問題,加了同步可以解決數據安全。

class Tickets implements Runnable{
 private int tickets = 100;
 private Object obj = new Object();
 public void run(){
  whilt(true){
   synchronized(obj){
    if(tickets>0){
     try{
      Thread.sleep(1000);
     }catch(Exception e){
      System.out.println(Thread.currentThread().getName()+tickets);
     }
    }
   }
  }
 }
}

餓漢式

class Single{
 private static final Single s = new Single();
 private Single(){)
 public static Single getInstance(){
  return s;
 }
}

懶漢式

class Single{
 private static Single s = null;
 private Single(){}
 public static Single getInstance(){
  if(s==null){
   s = new Single();
  }
 return s;
 }
}

多線程

在同一時間,做多件事情.

創建線程的方法
繼承類Thread並重寫run(),run()稱為線程體;用這種方法定義的類不能再繼承其他類。

class FirstThread extends Thread{
public void run(){
 for(int i=0;i<100;i++){
  System.out.println("FirstThread"+i);
 }
}
}

class Test{
public static void main(Sting args[]){
 FirstThread ft = new FirstThread();
 ft.start();
 
 for(int i = 0; i<100;i++){
  System.out.println("main"+i):
 }
}
}

介面Runnable的類作為線程的目標對象

class Test implements Runnable{
public void run(){
 for(int i = 0;i<100;i++){
  System.out.println("Runnable"+i);
 }
}
}

class Test{
public static void main(String args[]){
 Test test = new Test();
 Thread t = new Thread(test);
 System.out.println(t.getPriority());
 t.start();
}
}

喚醒線程

線程類
image.png

主方法類
image.png

線程同步與等待

image.png

線程的同步

關鍵字synchronized

多線程就是調用這個synchronized的方法的,
當線程用了這個方法,那麼其他線程想使用這個方法時就得等,直到線程使用完該調用的方法。

同步中的等待

wait()方法:暫時讓出cpu;
notifyAll()方法:等待結束。

線程是程式中的執行線程,在Java虛擬機中允許應用程式併發地運行多個執行線程,每個線程獨有它自己的一個優先順序,高的優先順序的執行線程優先於低優先順序的線程,每個線程都可以有或者不可以標記的一個守護程式。當一個線程中的運行代碼創建一個Thread對象的時候,該線程的初始化優先順序就被設定,只有創建線程是守護線程的時候,這個線程才是守護程式。

在Java中的虛擬機啟動,通常會有單個非守護線程,一般在代碼中有個線程為主線程,main方法。

第36節:Java當中的線程
第35節:Java面向對象中的多線程

這兩篇文章講了什麼是進程,什麼是線程等一些概念。

進程要執行需要依賴線程,線程是進程中最小的執行單位,一個進程中至少要有一個線程,線上程中串列是單條線程來執行多個任務來說的,任務A到任務B到任務C,只有任務A完成了後才開始到任務B,一條線完成。並行為開啟多個線程同時進行任務,同一時刻發生任務A,任務B,任務C。

什麼是線程安全

線程出現問題是在多線程的情況之下產生的。出現線程安全問題,如何去解決這個問題呢?用synchronized關鍵字,用來控制線程同步的,可以讓線程在多線程的情況下,不被多個線程同時執行,保證我們數據的安全性。

public synchronized void add(int i){
 ...
}

Lock的引入讓鎖有了可操作性,它是在Java1.6被引入進來的,Lock可以去手動獲取鎖和釋放鎖。

// ReentrantLock是Lock的子類
private Lock lock = new ReentrantLock(); 

private void methodThread(Thread thread){
       // 獲取鎖對象
       lock.lock(); 
       try {
           System.out.println(thread.getName() + "獲得了鎖");
       }catch(Exception e){
           e.printStackTrace();
       } finally {
           System.out.println(thread.getName() + "釋放了鎖");
           // 釋放鎖對象
           lock.unlock(); 
       }
}

往後餘生,努力學習
簡書作者:達叔小生
90後帥氣小伙,愛編程,愛運營,愛折騰。
簡書博客: https://www.jianshu.com/u/c785ece603d1

結語

  • 下麵我將繼續對其他知識 深入講解 ,有興趣可以繼續關註
  • 小禮物走一走 or 點贊

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 下載地址: https://github.com/imxiaoer/FloatToolBar 因為是個常見的功能,所以寫個組件。效果圖如下: 組件具體代碼如下: tool.vue 下載地址: https://github.com/imxiaoer/FloatToolBar ...
  • 幾米圈官網8個頁麵包括路由的配置在vue腳手架中進行開發,主要使用bootstrap完成頁面的佈局,amazeui完成動畫效果。vue腳手架單頁面開發路由切換其他子頁面主要遇到導入js和css的問題。在全局導入js插件時應該使用npm下載當前插件,在局部導入時,如果涉及到對現有界面中dom元素事件的 ...
  • 需求: 利用MySql資料庫結合前端技術完成用戶的註冊(要求不使用Web服務技術),所以 Demo採用Socket技術實現Web通信. 第一部分:資料庫創建 資料庫採用mysql 5.7.18, 資料庫名稱為MyUser, 內部有一張表 user.欄位有 Id,UserName,Psd,Tel 第二 ...
  • 1、event.stopPropagation 停止事件的傳播,阻止它被分配到其它Dom節點。但是不能阻止同一Dom節點上的其它事件句柄被調用。 2、event.preventDefault 阻止與事件關聯的預設動作。 ...
  • 本文轉自:http://developer.51cto.com/art/201709/552085.htm 本文轉自:https://www.cnblogs.com/stulzq/p/8573828.html 微服務架構現在是談到企業應用架構時必聊的話題,微服務之所以火熱也是因為相對之前的應用開發方 ...
  • 不管乾什麼,設定一個目標,針對一個目標有一個核心戰略,並堅決的執行核心戰略是取得勝利的不二法寶。 舉個慄子🌰: 三國三分天下。魏蜀吳都有自己的階段性核心戰略。魏國曹操的戰略是挾天子以令諸侯。東吳孫權的戰略是依靠天險,有水做天然屏障,孫吳水師一家獨大。蜀國的戰略是東聯孫權,北拒曹操。 魏國和吳國的執 ...
  • 前言 剛從事開發那段時間不習慣輸出日誌,認為那是無用功,徒增代碼量,總認為自己的代碼無懈可擊;老大的叮囑、強調也都視為耳旁風,最終導致的結果是我加班排查問題,花的時間還挺長的,要復現問題、排查問題等,幸虧那是公司內部員工用的系統,時間長一點也沒什麼大問題,但是如果是針對客戶的,時間就代表很多東西了, ...
  • c++ move關鍵字 move的由來:在 c++11 以前存在一個有趣的現象:T& 指向 lvalue (左傳引用), const T& 既可以指向 lvalue 也可以指向 rvalue。但卻沒有一種引用類型,可以限製為只指向 rvalue。 就這麼簡單!你甚至可以暫時想像它的原型是這樣的(當然 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...