探索Java并發編程--從基礎到高級實踐技巧

Thread(線程)

線程 = 程序執行的最小單位(一個進程至少有一個線程)。線程內有自己的執行棧、程序計數器(PC),但與同進程內其他線程共享堆內存與進程資源

在java中,線程由java.lang.Thread表示,但我們通常不直接操作裸線程,而用更高層的并發工具(線程池、任務、并發集合等)

一、線程的生命周期與常見操作

狀態:NEW、RUNNABLE、BLOCKED / WAITING / TIMED_WAITING、TERMINATED

  • NEW:對象創建后,未start()
  • RUNNABLE:可運行(包括實際運行或等待運行)
  • BLOCKED:等待獲取對象監視器(synchronized)
  • WAITING:等待其他線程通知(Object.wait()、Thread.join()無超時)
  • TERMINATED:run方法返回或拋出異常結束

常用方法:

  • start():啟動線程(不要直接調用run,會變成普通方法調用)
  • join():等待線程結束
  • sleep():當前線程休眠(會釋放CPU,但不釋放鎖)
  • interrupt():中斷線程(合作式,需要線程內檢查isInterrupted()或捕獲InterruptedException)
  • yield():禮讓(建議少用,平臺依賴)

二、創建線程

  1. 繼承Thread
// 問題:單繼承限制、職責不清(把任務和線程綁定)
class MyThread extends Thread {public void run() { /* 任務 */ }
}
new MyThread().start();
  1. 實現Runnable
// 好處:解耦任務和線程、可復用
Runnable task = () -> { /* 任務 */ };
new Thread(task).start();
  1. 實現Callable + Future(用于返回值 / 異常)
// 支持返回值和拋異常
Callable<Integer> c = () -> 1+2;
Future<Integer> f = executor.submit(c);
Integer result = f.get(); // 阻塞取結果
  1. 使用線程池(ExecutorService / ThreadPoolExecutor)
ExecutorService pool = Executors.newFixedThreadPool(5);
pool.submit(() -> { /* 任務 */ });
pool.shutdown();
// 不要濫用Executor.*生成的未定制池(可能使用無界隊列或者不合適的場景)一般直接構造ThreadPoolExecutor并調參
  1. ForkJoinPool(分治、并行流)
  • 適合CPU密集型、可分解任務(RecursiveTask)。采用工作竊取(work-stealing)
  1. CompletableFuture(異步組合)
  • 異步流式編程supplyAsync、鏈式 thenApply、異常處理 exceptionally,能把異步任務組合成復雜流程。
  1. 虛擬線程(Project Loom —— 概念)
  • 新一代思想:大量“輕量級線程”由 JVM 管理,降低線程/請求的成本,能用同步編程模型寫大并發程序。
  • (提示:具體語法/可用性隨 JDK 版本變化,寫生產代碼前確認 JDK 支持情況。)

三、同步與內存可見性

并發核心問題是:共享可變狀態會導致競態、可見性問題

  1. synchronized(內置鎖)

    • 監視器(monitor):synchronized修飾方法或代碼塊
    • 可重入(同一線程可重復獲得同一把鎖)
    • wait() / notify() / notifyAll()在持鎖狀態下使用,用于線程間協作
    // 特點:保證同一時刻只有一個線程能執行臨界區代碼,并且進入 / 退出時會觸發內存可見性更新/*單例模式(懶漢式加鎖)
    */
    public class Singleton {private static Singleton instance;public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
    }/*多線程安全更新共享資源
    */
    public class Counter {private int count = 0;public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
    }/*保證集合安全(eg:ArrayList在多線程下不安全,可用Collections.synchronizedList包裝)
    */
    
  2. volatile

    • 保證可見性(寫入一個volatile變量后,后續讀能看到最新值)和禁止指令重排序(對單個變量)
    • 不能替代鎖來保證復合操作的原子性(比如count++不是原子性)
    // 特點:讓一個線程修改的變量能立即被其他線程看到;禁止指令重排序。
    //     適合 狀態標志、開關類變量
    /*線程停止標志
    */
    class Task implements Runnable {private volatile boolean running = true;public void run() {while (running) {// do work...}}public void stop() {running = false; // 立刻被其他線程看到}
    }
    /*配置熱更新一個后臺線程定時刷新配置,把值寫入volatile變量,業務線程能馬上讀到新值
    */// 注意:下面這種情況要用synchronized或AtomicInteger
    
  3. Lock(java.util.concurrent.locks)

    • ReentrantLock:比synchronized更靈活(可中斷獲取鎖、可輪詢、可超時),支持Condition(類似多個wait / nottify集合)
    • ReadWriteLock:讀寫分離鎖,讀多寫少場景有利
    // 顯示鎖,比synchronized更靈活,可定時、可中斷、支持多個條件隊列
    /*嘗試獲取鎖(避免死等)
    */
    ReentrantLock lock = new ReentrantLock();
    if (lock.tryLock(1, TimeUnit.SECONDS)) {try {// 臨界區} finally {lock.unlock();}
    } else {// 獲取鎖失敗,執行降級邏輯
    }/* 讀寫分離(適合讀多寫少)
    */
    ReadWriteLock rwLock = new ReentrantReadWriteLock();
    Lock r = rwLock.readLock();
    Lock w = rwLock.writeLock();
    
  4. 原子類(AtomicInteger / Long / Reference)

    • 基于CAS(無鎖算法),用于計數等簡單場景。注意ABA問題(可用AtomicStampedReference)
    // 基于CAS實現的無鎖并發,常用于計數器、序列號
    /*高性能計數器
    */
    private AtomicInteger count = new AtomicInteger();
    public void increment() {count.incrementAndGet();
    }/*并發限流 / 統計QPS、在線人數統計,避免用synchronized降低性能
    */
    
  5. 內存模型(JMM)要點

    • 主內存 + 工作內存(線程本地緩存),寫到主內存后其他線程可見。volatile / 鎖會產生內存屏障,保證可見性與有序性

四、常用并發工具(java.util.concurrent)

  • 線程池:ThreadoolExecutor(核心、最大線程數、隊列、飽和策略)
  • 阻塞隊列:ArrayBlockingQueue,LinkBlockingQueue,PriorityBlockQueue(常用于生產者-消費者)
  • 同步輔助類:CountDownLatch, CyclicBarrier, Semaphore, Phaser, Exchanger
  • 并發集合:ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueue
  • ForkJoinPool(并行任務)
  • BlockingQueue + ThreadPool:典型生產者-消費者模式
  • FutureTask:可作為Runnable也可獲取結果,常用于把Callable封裝成任務

五、線程安全問題與常見陷阱

  • 競態條件(race condition):并發修改同一狀態導致錯誤結果
  • 死鎖(deadlock):兩個或多個線程互相持有對方需要的鎖。四要素:互斥、持有并等待、不可剝奪、循環等待
  • 活鎖(livelock):線程不斷執行但無法取得進展(一直讓步)
  • 饑餓(starvation):某線程長期無法獲得CPU或鎖資源
  • 優先級反轉(priority inversion):低優先級線程持鎖導致高優先級線程等待
  • 內存泄露(ThreadLocal):線程池中使用ThreadLocal若不remove(),會造成對象無法回收(尤其在容器應用中)

排查工具:jstack(線程dump)、jvisualvm、jconsole、應用日志、線程名 / ID打點、Flight Recorder。線程dump是定位死鎖 / 阻塞的利器

六、守護線程(Daemon)vs 用戶線程(User)

  • 用戶線程:只要存在任意用戶線程,JVM不會退出
  • 守護線程:JVM在所有用戶線程結束后會退出,即使守護線程還在跑

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96303.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go語言實戰案例-開發一個Markdown轉HTML工具

這個小工具可以把 .md 文件轉換為 .html 文件&#xff0c;非常適合寫筆記、博客或者快速預覽 Markdown 內容。&#x1f4cc; 案例目標? 讀取一個 Markdown 文件? 使用開源庫將 Markdown 轉換為 HTML? 將 HTML 輸出到新文件中&#x1f4e6; 所需庫我們用 goldmark 這個 Markd…

基于51單片機的太陽能鋰電池充電路燈

基于51單片機的太陽能鋰電池充電路燈系統設計 1 系統功能介紹 本設計以 STC89C52單片機 為核心&#xff0c;構建了一個能夠利用太陽能為鋰電池充電并智能控制LED路燈的系統。系統結合了 光照檢測電路、LED燈電路、按鍵檢測電路、太陽能充電電路 等模塊&#xff0c;實現了節能、…

PAT 1178 File Path

這一題的大意是給出了一個windows的文件夾目錄&#xff0c;讓我們按照所屬的目錄關系&#xff0c;來找相應的目錄是否存在&#xff0c;如果存在&#xff0c;就輸出找到該文件的路徑&#xff0c;如果不存在輸出error 我的思路是用合適的樹形結構保存下來目錄的所屬關系&#xff…

云原生部署_k8s入門

K8S官網文檔&#xff1a;&#xfeff;https://kubernetes.io/zh/docs/home/Kubernetes是什么Kubernetes 是用于自動部署、擴縮和管理容器化應用程序的開源系統。 Kubernetes 源自 &#xff0c;Google 15 年生產環境的運維經驗同時凝聚了社區的最佳創意和實踐。簡稱K8s.Kubernet…

實戰項目-----Python+OpenCV 實現對視頻的椒鹽噪聲注入與實時平滑還原”

實戰項目實現以下功能&#xff1a;功能 1&#xff1a;為視頻每一幀添加椒鹽噪聲作用&#xff1a;模擬真實環境中圖像傳輸或采集時可能出現的噪聲。實現方式&#xff1a;讀取視頻的每一幀。隨機選擇 10000 個像素點&#xff0c;將其設置為黑色&#xff08;0&#xff09;或白色&a…

Day42 PHP(mysql注入、跨庫讀取)

一、sql注入基本原理&#xff1a;沒有對用戶輸入的數據進行限制&#xff0c;導致數據庫語句可以做什么&#xff0c;用戶就可以做什么。取決于不同數據庫的不同查詢語言&#xff0c;所以為什么有mysql注入/orcale注入等等。步驟&#xff1a;【access】表名&#xff08;字典爆破來…

機器人控制器開發(部署——軟件打包備份更新)

文章總覽 為什么做備份更新 為機器人控制器設計一套打包備份更新機制&#xff0c;為控制器的批量生產和產品與項目落地做準備。 當某個模塊出現bug需要升級時&#xff0c;用戶可以快速獲取正確的bak包并導入到控制器中重啟生效。 如果沒有做好軟件的備份更新機制&#xff0c…

LaTeX TeX Live 安裝與 CTAN 國內鏡像配置(Windows / macOS / Linux 全流程)

這是一份面向國內環境的 LaTeX 從零到可編譯 指南&#xff1a;覆蓋 TeX Live / MacTeX 安裝、PATH 配置、CTAN 國內鏡像&#xff08;清華/北外/上交/中科大等&#xff09;一鍵切換與回滾、常見坑位&#xff08;權限、鏡像路徑、版本切換&#xff09;、以及 XeLaTeX/latexmk 的實…

WhoisXML API再次榮登2025年美國Inc. 5000快速成長企業榜單

WhoisXML API非常自豪地宣布&#xff0c;我們再次榮登美國權威榜單——2025年Inc.5000全美成長最快的私營企業之一。今年&#xff0c;公司在地區排名中位列第119名&#xff0c;在全美總體排名中位列第4,271名。Inc. 5000榜單要求參評企業必須保持獨立運營&#xff0c;并在2021至…

Elasticsearch面試精講 Day 9:復合查詢與過濾器優化

【Elasticsearch面試精講 Day 9】復合查詢與過濾器優化 在Elasticsearch的搜索體系中&#xff0c;復合查詢&#xff08;Compound Queries&#xff09;與過濾器&#xff08;Filters&#xff09;優化是構建高效、精準搜索邏輯的核心能力。作為“Elasticsearch面試精講”系列的第…

Android使用ReactiveNetwork監聽網絡連通性

引入庫 implementation com.github.pwittchen:reactivenetwork-rx2:3.0.8監聽網絡連接變更ReactiveNetwork.observeNetworkConnectivity(context).subscribeOn(Schedulers.io())// ... // anything else what you can do with RxJava.observeOn(Schedulers.computation()).subs…

基于阿里云部署 RustDesk 自托管服務器

基于阿里云部署 RustDesk 自托管服務器一、背景與需求場景二、什么是 RustDesk&#xff1f;為什么選擇自托管&#xff1f;2.1 RustDesk 是什么&#xff1f;2.2 為什么選擇自托管&#xff1f;三、環境準備與架構說明四、操作步驟4.1 在阿里云上安裝 RustDesk 服務端4.1.1 下載并…

細說分布式ID

針對高并發寫&#xff0c;分布式ID是其業務基礎&#xff0c;本文從一個面試題細細展開。面試官&#xff1a;1.對于Mysql的InnoDB引擎下&#xff0c;自增ID和UUID作為主鍵各自有什么優劣&#xff0c;對于一張表的主鍵你建議使用哪種ID&#xff1f;2.除了UUID是否還了解其他類型的…

2025年大數據專業證書報考指南:專科學歷必看的8大選擇?

對于大專學歷的同學來說&#xff0c;2025年進入大數據行業是一個充滿機遇的選擇。大數據領域發展迅速&#xff0c;各類證書能夠幫助求職者提升專業能力、增強就業競爭力。其中最推薦的是CDA數據分析師&#xff0c;這個證書適應了未來數字化經濟和AI發展趨勢&#xff0c;難度不高…

Python爬蟲實戰:研究Axis Artist模塊,構建電商數據采集和分析系統

1. 引言 1.1 研究背景與意義 在大數據時代,互聯網上蘊藏著海量有價值的信息,這些信息涵蓋了社會、經濟、科技等各個領域。高效地從互聯網獲取數據并進行深度分析,對于企業決策、學術研究、市場分析等都具有重要意義。Python 作為一種功能強大的編程語言,憑借其豐富的庫支…

突破大語言模型推理瓶頸:深度解析依賴關系與優化策略

突破大語言模型推理瓶頸&#xff1a;深度解析依賴關系與優化策略當ChatGPT需要5秒才能生成一個回答&#xff0c;當企業級大模型每秒只能處理3個用戶請求——這些性能瓶頸的背后&#xff0c;隱藏著大語言模型推理計算中復雜的依賴關系網。在大語言模型推理過程中&#xff0c;依賴…

整理了幾道前端面試題

1. 若是有兩個數組ar1和ar2&#xff0c;求它們的并集和交集&#xff0c;要怎么做&#xff1f; const ar1 [1, 2, 3, 4]; const ar2 [3, 4, 5, 6];一、求并集 (Union) 目標&#xff1a; 把兩個數組合并成一個新數組&#xff0c;新數組包含所有出現過的元素&#xff0c;但每個…

Mac M4環境下基于VMware Fusion虛擬機安裝Ubuntu24.04 LTS ARM版

Mac M4環境下基于VMware Fusion虛擬機安裝Ubuntu24.04 LTS ARM版 1 下載Ubuntu鏡像 在Ubuntu官網下載Ubuntu24.04 LTS的arm版鏡像&#xff0c;這里選擇ubuntu-24.04-live-server-arm64.iso&#xff0c;支持arm的似乎沒有合適的desktop版本&#xff0c;Server版本默認是不帶圖…

開源與定制化對比:哪種在線教育系統源碼更適合教育培訓APP開發?

如今&#xff0c;“在線教育系統源碼”已經成為許多教育培訓機構、創業者甚至傳統學校的高頻關鍵詞。無論是打造一款在線教育APP&#xff0c;還是開發企業內部培訓平臺&#xff0c;源碼選擇都決定了后續的開發效率、產品體驗與商業化潛力。 在實際開發中&#xff0c;常見的源碼…

中間件的日志分析

將日志文件access.log復制到kali中進行分析使用命令查看文件中各IP的訪問次數&#xff0c;依次分析其行為awk { print $1 } access.log | sort | uniq -c |sort -nr172.16.3.189cat access.log | grep 172.16.3.198行為模式分析使用固定弱密碼進行身份驗證 幾乎所有請求都使用用…