Java基礎 Day25

一、線程通信

1、簡介

確保線程能夠按照預定的順序執行并且能夠安全地訪問共享資源

使多條線程更好的進行協同工作

2、常用方法

void?wait()

使當前線程進入等待狀態

void?notify();

隨機喚醒單個等待的線程(可以空喚醒)

void notifyAll();

喚醒所有等待的線程

這些方法來自Object類,需要使用鎖對象進行調用

3、注意事項

(1)sleep方法和wait方法的區別

sleep是線程休眠,時間到了自動醒來,休眠時不會釋放鎖

wait是線程等待,需要其他線程進行喚醒,等待時會釋放鎖

(2)所有醒著的線程都有概率搶到CPU

(3)線程被喚醒之后(若搶到CPU),從之前進入等待的地方繼續往下執行

4、等待喚醒機制

使用 ReentrantLock 實現同步,并獲取 Condition 對象,使用 Condition 對象調用以下方法

void?await()

指定線程等待

void?signal();

指定喚醒單個等待的線程

public class AwaitDemo {public static void main(String[] args) {Printer2 p = new Printer2();new Thread(new Runnable() {public void run() {while (true) {try {p.print1();} catch (InterruptedException e) {throw new RuntimeException(e);}}}}).start();new Thread(new Runnable() {public void run() {while (true) {try {p.print2();} catch (InterruptedException e) {throw new RuntimeException(e);}}}}).start();new Thread(new Runnable() {public void run() {while (true) {try {p.print3();} catch (InterruptedException e) {throw new RuntimeException(e);}}}}).start();}
}class Printer2 {int flag = 1;ReentrantLock myLock = new ReentrantLock();Condition c1 = myLock.newCondition();Condition c2 = myLock.newCondition();Condition c3 = myLock.newCondition();public void print1() throws InterruptedException {myLock.lock();if (flag != 1) {c1.await();}System.out.print(1);System.out.println(1);flag = 2;c2.signal();myLock.unlock();}public void print2() throws InterruptedException {myLock.lock();if (flag != 2) {c2.await();}System.out.print(2);System.out.println(2);flag = 3;c3.signal();myLock.unlock();}public void print3() throws InterruptedException {myLock.lock();if (flag != 3) {c3.await();}System.out.print(3);System.out.println(3);flag = 1;c1.signal();myLock.unlock();}
}循環輸出:
11
22
33

Tips:對于一個Condition對象,哪個線程最先使用該對象調用await方法,該對象就綁定到該線程

如果使用一個未綁定線程的Condition對象調用signal方法,將會隨機喚醒一個線程

5、生產者消費者模式

生產者消費者模式是一個十分經典的多線程協作的模式

包含了兩類線程:

生產者線程,用于生產數據

消費者線程,用于消費數據

為了解耦生產者和消費者的關系,通常會采用共享的數據區域 (緩沖區),就像是一個倉庫

生產者生產數據之后直接放置在共享數據區中,并不需要關心消費者的行為

消費者只需要從共享數據區中去獲取數據,并不需要關心生產者的行為

public class ProducerAndConsumer {public static void main(String[] args) {new Thread(new Producer()).start();new Thread(new Consumer()).start();}
}class SharedData {public static boolean flag = false;public static ReentrantLock lock = new ReentrantLock();public static Condition producer = lock.newCondition();public static Condition consumer = lock.newCondition();
}class Producer implements Runnable {@Overridepublic void run() {while (true) {SharedData.lock.lock();if (!SharedData.flag) {System.out.println("produce");try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}SharedData.flag = true;SharedData.consumer.signal();} else {try {SharedData.producer.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}SharedData.lock.unlock();}}
}class Consumer implements Runnable {@Overridepublic void run() {while (true) {SharedData.lock.lock();if (SharedData.flag) {System.out.println("consume");try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}SharedData.flag = false;SharedData.producer.signal();} else {try {SharedData.consumer.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}SharedData.lock.unlock();}}
}

二、線程生命周期

線程被創建并啟動以后,它并不是一啟動就進入了執行狀態,也不是一直處于執行狀態。

線程對象在不同的時期有不同的狀態

NEW(新建)

創建線程對象,還沒調用 start 方法

RUNNABLE(就緒)

start?方法被調用,但是還沒有搶到?CPU?執行權

BLOCKED(阻塞)

線程開始運行,但是沒有獲取到鎖對象

WAITING(等待)

wait?方法

TIMED_WAITING(計時等待)

sleep?方法

TERMINATED(結束狀態)

代碼全部運行完畢

三、線程池

1、簡介

系統創建一個線程的成本是比較高的,因為它涉及到與操作系統交互

當程序中需要創建大量生存期很短暫的線程時,頻繁的創建和銷毀線程,就會嚴重浪費系統資源

將線程對象交給線程池維護

可以降低系統成本,提升程序的性能

實際開發中,線程資源必須通過線程池提供,不允許在線程中自行顯示創建線程

2、JDK 提供的線程池(實際開發中不使用)

Executors 中提供靜態方法來創建線程池

static?ExecutorService?newCachedThreadPool?()

創建一個默認的線程池

static?newFixedThreadPool?(int?nThreads)

創建一個指定最多線程數量的線程池?

3、自定義線程池

(1)ThreadPoolExecutor 類的構造方法:七個參數

ThreadPoolExecutor(int corePoolSize,  // 核心線程數int maximumPoolSize,  // 最大線程數 = 核心線程數 + 最大臨時線程數long keepAliveTime, // 等待時間,超過該時間就刪除臨時線程TimeUnit unit, // 等待時間的單位BlockingQueue<Runnable> workQueue, // 任務隊列(要指定最大任務數)ThreadFactory threadFactory, // 線程對象任務工廠(用于創建臨時對象)RejectedExecutorHandler handler // 拒絕策略
)

?

(2)拒絕策略

ThreadPoolExecutor.AbortPolicy?

丟棄任務并拋出RejectedExecutionException異常?(默認,推薦)

ThreadPoolExecutor.DiscardPolicy

丟棄任務,但是不拋出異常,這是不推薦的做法

ThreadPoolExecutor.DiscardOldestPolicy

拋棄隊列中等待最久的任務,然后把當前任務加入隊列中

ThreadPoolExecutor.CallerRunsPolicy

調用任務的run()方法,繞過線程池直接執行

(3)注意事項

臨時線程什么時候創建?

線程任務數 > 核心線程數 + 任務隊列的數量

什么時候會開啟拒絕策略?

線程任務數 > 最大線程數 + 任務隊列的數量

public class ThreadPoolDemo {public static void main(String[] args) {ThreadPoolExecutor pool = new ThreadPoolExecutor(2,5,60,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 16; i++) {pool.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " submitted");}});}}
}

四、單例設計模式

單例指單個實例,保證類的對象在內存中只有一份

使用場景:

如果創建一個對象需要消耗的資源過多,比如 I/O 與數據庫的連接

并且這個對象完全是可以復用的, 我們就可以考慮將其設計為單例的對象

class Single1 {private Single1() {}private static Single1 s = new Single1();public static Single1 getInstance() {return s;}
}class Single2 {  // 延遲加載模式private Single2() {}private static Single2 s;public static Single2 getInstance() {if (s == null) {synchronized (Single2.class) {if (s == null) {s = new Single2();}}}return s;}
}

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

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

相關文章

WebSocket與實時對話式AI服務的集成

WebSocket與實時對話式AI服務的集成 在現代對話式AI系統中,傳統的HTTP請求-響應模型已難以滿足實時交互的體驗需求。特別是用戶對響應速度、逐字輸出、會話上下文保持等方面提出更高要求時,需要一種能夠建立持久連接并支持雙向通信的協議。WebSocket正是在這一背景下,成為A…

iOS 集成網易云信IM

云信官方文檔在這 看官方文檔的時候&#xff0c;版本選擇最新的V10。 1、CocoPods集成 pod NIMSDK_LITE 2、AppDelegate.m添加頭文件 #import <NIMSDK/NIMSDK.h> 3、初始化 NIMSDKOption *mrnn_option [NIMSDKOption optionWithAppKey:"6f6568e354026d2d658a…

人工智能100問?第37問:什么是擴散模型?

目錄 ??一、通俗解釋 二、專業解析?? 三、權威參考 擴散模型是一種??通過系統性地添加再去除噪聲來生成新數據(如圖像)的生成式AI技術??,其核心機制分為兩個階段:正向擴散??:對原始數據(如清晰圖片)逐步添加噪聲,直至完全變成隨機噪點(類似老照片逐漸模糊…

傳輸層核心技術解析

目錄 一、端口號機制 二、網絡診斷工具 1. netstat命令 2. pidof工具 三、UDP協議詳解 協議特征 典型應用場景 四、TCP協議深度解析 核心機制 狀態轉換模型 特殊狀態說明 五、協議對比分析 六、開發實踐要點 一、端口號機制 核心作用&#xff1a;標識主機唯一進程…

IO Vs NIO

一、IO(傳統阻塞式) 全稱?&#xff1a;Input/Output(輸入/輸出) 定義?&#xff1a;Java 1.0 引入的基礎 I/O 模型&#xff0c;基于流&#xff08;Stream&#xff09;的同步阻塞操作&#xff0c;線程在讀寫數據時會阻塞直到操作完成。 二、NIO(新式非阻塞式) ?全…

基于原生JavaScript前端和 Flask 后端的Todo 應用

Demo地址&#xff1a;https://gitcode.com/rmbnetlife/todo-app-js-flask.git Python Todo 應用 這是一個使用Python Flask框架開發的簡單待辦事項(Todo)應用&#xff0c;采用前后端分離架構。本項目實現了待辦事項的添加、刪除、狀態切換等基本功能&#xff0c;并提供了直觀…

005 ElasticSearch 許可證過期問題

ElasticSearch 許可證過期問題 項目啟動報錯 org.elasticsearch.client.ResponseException: method [GET], host [http://127.0.0.1:9200], URI [/_cluster/health/], status line [HTTP/1.1 403 Forbidden] {"error":{"root_cause":[{"type":…

哪些崗位最易被AI替代?

隨著AI技術高速演進&#xff0c;一場“職場大洗牌”正悄然上演。當ChatGPT出口成章、機器人能精準執勤&#xff0c;AI時代的“就業焦慮”已不再是空談。你是否認真思考過&#xff0c;自己所處的崗位是否也正面臨被AI邊緣化的風險&#xff1f; 以下幾類職業&#xff0c;已成為AI…

信號槽中 sender() 的作用

好的,sender() 是 Qt 框架中的一個重要函數,它用于獲取觸發當前槽函數的對象。在 Qt 的信號和槽機制中,一個信號可以連接到多個槽函數,而一個槽函數也可以被多個信號觸發。sender() 函數允許你在槽函數中確定是哪個對象觸發了當前信號。 信號和槽機制 在 Qt 中,信號和槽…

深度學習|pytorch基本運算

【1】引言 pytorch是深度學習常用的包&#xff0c;顧名思義&#xff0c;就是python適用的torch包&#xff0c;在python里面使用時直接import torch就可以調用。 需要注意的是&#xff0c;pytorch包與電腦配置、python版本有很大關系&#xff0c;一定要仔細閱讀安裝要求、找到…

DeepSeek 賦能數字人直播帶貨:技術革新重塑電商營銷新生態

目錄 一、引言二、DeepSeek 技術探秘2.1 DeepSeek 技術原理剖析2.2 DeepSeek 與其他大模型對比優勢 三、數字人直播帶貨現狀洞察3.1 數字人直播帶貨發展歷程回顧3.2 市場規模與增長趨勢分析3.3 現存問題與挑戰探討 四、DeepSeek 在數字人直播帶貨中的應用實例4.1 交個朋友的成功…

實驗設計與分析(第6版,Montgomery)第5章析因設計引導5.7節思考題5.11 R語言解題

本文是實驗設計與分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅玨生譯) 第5章析因設計引導5.7節思考題5.11 R語言解題。主要涉及方差分析&#xff0c;正態假設檢驗&#xff0c;殘差分析&#xff0c;交互作用圖。 dataframe<-data.frame( densityc(570,565,…

四、關系數據庫標準語言SQL_1

四、關系數據庫標準語言SQL_1 主要內容 4.1 SQL概述 SQL簡介 4.2 SOL的系統結構4.3 SQL數據定義 SQL的數據定義 4.5 SQL數據查詢4.6 SQL數據更新4.7 SQL中的視圖4.8 SQL的數據控制4.9 嵌入式SQL小結 4.1 SQL概述 主要內容 SQL簡介SQL的特點SQL的系統結構 SQL簡介 SQL&…

vscode的Embedded IDE創建keil項目找不到源函數或者無法跳轉

創建完Embedded IDE項目后跳轉索引很容易找不到源函數或者無法跳轉&#xff0c;原因是vscode工作區被eide覆蓋了&#xff0c;需要手動往當前目錄下的.vscode/c_cpp_properties.json里添加路徑 打開eide.json &#xff0c;找到folders&#xff0c; 里面的name是keil里工程的虛擬…

【Docker管理工具】部署Docker管理面板DweebUI

【Docker管理工具】部署Docker管理面板DweebUI 一、DweebUI介紹1.1 DweebUI 簡介1.2 主要特點1.3 使用場景 二、本次實踐規劃2.1 本地環境規劃2.2 本次實踐介紹 三、本地環境檢查3.1 檢查Docker服務狀態3.2 檢查Docker版本3.3 檢查docker compose 版本 四、下載DweebUI鏡像五、…

CentOS7.9環境離線部署docker和docker-compose的兩種方式

目 錄 一、yum安裝&#xff0c;使用rpm安裝包和相關依賴 1.1 準備rpm安裝包 1.2 將docker-23.0.4.tar.gz上傳至/opt目錄下 二、二進制文件方式安裝 三、安裝docker-compose 一、yum安裝&#xff0c;使用rpm安裝包和相關依賴 1.1 準備rpm安裝包 1&#xff09;在一臺與…

AI賦能SEO關鍵詞策略

內容概要 當前搜索引擎優化領域正經歷由人工智能驅動的范式革新。傳統關鍵詞研究依賴人工統計與經驗判斷&#xff0c;而AI技術通過多維數據建模與自然語言處理&#xff0c;實現了從用戶行為分析到語義關聯挖掘的系統升級。具體而言&#xff0c;智能語義解析技術可穿透表層搜索…

MonoPCC:用于內窺鏡圖像單目深度估計的光度不變循環約束|文獻速遞-深度學習醫療AI最新文獻

Title 題目 MonoPCC: Photometric-invariant cycle constraint for monocular depth estimation of endoscopic images MonoPCC&#xff1a;用于內窺鏡圖像單目深度估計的光度不變循環約束 01 文獻速遞介紹 單目內窺鏡是胃腸診斷和手術的關鍵醫學成像工具&#xff0c;但其…

使用基于Xsens慣性傳感器的動作捕捉技術測量人體工程學

由于單調和片面的體力消耗&#xff0c;牙科領域的從業者患肌肉骨骼疾病 (MSD) 的幾率很高。慣性測量單元 (IMU) 越來越成為評估工作姿勢風險的焦點。因此&#xff0c;本研究旨在使用基于慣性傳感器的運動捕捉 (MoCap) 評估人體工程學講座和培訓干預對牙科助理學生的姿勢風險和M…

抗輻照加固CANFD芯片:以車規級設計提升商業航天系統可靠性

摘要 商業航天領域的發展對電子系統的可靠性和抗輻照能力提出了更高要求。本文深入探討了抗輻照加固CANFD芯片如何借助車規級設計&#xff0c;增強商業航天系統的可靠性。本文以國科安芯CANFD芯片ASM1042為例&#xff0c;通過對芯片單粒子效應脈沖激光試驗報告、數據手冊及芯片…