Java多線程實現(xiàn)之線程調(diào)度的使用
Java多線程中線程調(diào)度是一個核心概念,它決定了線程如何獲得CPU資源并執(zhí)行。合理的線程調(diào)度策略能夠充分發(fā)揮多核處理器的性能,提高程序的執(zhí)行效率。本文我將深入探討Java線程調(diào)度的原理、機制以及相關(guān)的API,帶你更好地理解和控制線程的執(zhí)行。
一、線程調(diào)度基礎(chǔ)概念
1.1 線程調(diào)度器
線程調(diào)度器是JVM的一部分,負責決定哪個線程獲得CPU時間片以及執(zhí)行多長時間。Java線程調(diào)度器采用搶占式調(diào)度模型,即高優(yōu)先級的線程可以搶占低優(yōu)先級線程的CPU資源。
1.2 時間片
時間片是線程在CPU上執(zhí)行的最小時間單位。調(diào)度器會為每個線程分配一個時間片,當時間片用完后,該線程會被暫停執(zhí)行,調(diào)度器會選擇另一個線程執(zhí)行。
1.3 線程狀態(tài)轉(zhuǎn)換
線程在其生命周期中會經(jīng)歷多種狀態(tài),調(diào)度器在這些狀態(tài)之間進行轉(zhuǎn)換:
- 新建(New):線程被創(chuàng)建但尚未啟動
- 就緒(Runnable):線程正在等待CPU資源
- 運行(Running):線程正在CPU上執(zhí)行
- 阻塞(Blocked):線程因等待鎖、IO等原因暫停執(zhí)行
- 等待(Waiting):線程等待其他線程通知
- 超時等待(Timed Waiting):線程在指定時間內(nèi)等待
- 終止(Terminated):線程執(zhí)行完畢或異常終止
二、線程優(yōu)先級
2.1 優(yōu)先級范圍
Java線程優(yōu)先級范圍從1到10,數(shù)值越大優(yōu)先級越高:
Thread.MIN_PRIORITY= 1Thread.NORM_PRIORITY= 5(默認優(yōu)先級)Thread.MAX_PRIORITY= 10
2.2 設(shè)置線程優(yōu)先級
通過setPriority(int priority)方法設(shè)置線程優(yōu)先級:
Thread highPriorityThread = new Thread(() -> {
// 高優(yōu)先級線程任務(wù)
});
highPriorityThread.setPriority(Thread.MAX_PRIORITY);
Thread lowPriorityThread = new Thread(() -> {
// 低優(yōu)先級線程任務(wù)
});
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
2.3 優(yōu)先級注意事項
- 優(yōu)先級不保證執(zhí)行順序:高優(yōu)先級線程只是更有可能獲得CPU資源,但不保證一定先執(zhí)行
- 平臺依賴性:不同操作系統(tǒng)對線程優(yōu)先級的支持不同,可能導(dǎo)致優(yōu)先級行為不一致
- 避免過度依賴優(yōu)先級:應(yīng)通過合理的同步機制而非優(yōu)先級來控制線程執(zhí)行順序
三、線程調(diào)度方法
3.1 Thread.sleep(long millis)
使當前線程暫停執(zhí)行指定的毫秒數(shù),線程進入超時等待狀態(tài):
try {
Thread.sleep(1000); // 暫停1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
3.2 Thread.yield()
提示調(diào)度器當前線程愿意讓出CPU資源,線程進入就緒狀態(tài):
public void run() {
for (int i = 0; i < 100; i++) {
// 執(zhí)行一些工作
if (i % 10 == 0) {
Thread.yield(); // 讓出CPU資源
}
}
}
3.3 Thread.join()
等待指定線程執(zhí)行完畢:
Thread t = new Thread(() -> {
// 執(zhí)行耗時操作
});
t.start();
try {
t.join(); // 等待線程t執(zhí)行完畢
} catch (InterruptedException e) {
e.printStackTrace();
}
3.4 Object.wait() / notify() / notifyAll()
用于線程間通信,實現(xiàn)線程的協(xié)作:
class SharedResource {
private boolean ready = false;
public synchronized void waitForReady() throws InterruptedException {
while (!ready) {
wait(); // 線程等待
}
}
public synchronized void setReady() {
ready = true;
notifyAll(); // 喚醒所有等待的線程
}
}
四、線程調(diào)度策略
4.1 搶占式調(diào)度
Java默認采用搶占式調(diào)度,高優(yōu)先級線程可以搶占低優(yōu)先級線程的CPU資源。但這種搶占不是絕對的,具體還取決于操作系統(tǒng)的調(diào)度策略。
4.2 公平鎖與非公平鎖
- 公平鎖:線程按照請求鎖的順序獲得鎖,保證公平性但可能降低吞吐量
- 非公平鎖:允許線程在鎖釋放時直接競爭,可能導(dǎo)致某些線程長期得不到鎖
4.3 守護線程
守護線程是為其他線程提供服務(wù)的線程,當所有非守護線程結(jié)束時,JVM會自動終止守護線程:
Thread daemonThread = new Thread(() -> {
// 守護線程任務(wù)
});
daemonThread.setDaemon(true); // 設(shè)置為守護線程
daemonThread.start();
五、線程池中的調(diào)度
5.1 線程池的調(diào)度策略
線程池通過ExecutorService接口提供,常見的線程池實現(xiàn)有:
FixedThreadPool:固定大小的線程池CachedThreadPool:可緩存的線程池ScheduledThreadPool:支持定時任務(wù)的線程池
5.2 自定義線程池調(diào)度
通過ThreadPoolExecutor可以自定義線程池的調(diào)度策略:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心線程數(shù)
10, // 最大線程數(shù)
60, // 空閑線程存活時間
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // 任務(wù)隊列
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);
六、線程調(diào)度的最佳實踐
6.1 避免過度依賴優(yōu)先級
線程優(yōu)先級應(yīng)謹慎使用,過度依賴優(yōu)先級可能導(dǎo)致程序行為不穩(wěn)定,尤其是在不同操作系統(tǒng)上。
6.2 合理使用sleep和yield
sleep()用于精確控制線程暫停時間yield()用于提示調(diào)度器讓出CPU資源,但不保證一定會讓出
6.3 優(yōu)先使用線程池
線程池提供了更高級的調(diào)度控制和資源管理,應(yīng)優(yōu)先使用線程池而非手動創(chuàng)建線程。
6.4 正確處理線程中斷
在線程中正確處理InterruptedException,確保線程可以被優(yōu)雅地終止:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// 線程任務(wù)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢復(fù)中斷狀態(tài)
break;
}
}
}
總結(jié)
Java線程調(diào)度是一個復(fù)雜的機制,涉及優(yōu)先級、狀態(tài)轉(zhuǎn)換、同步等多個方面,理解線程調(diào)度的原理和機制,能夠幫助我們更好地控制線程執(zhí)行,提高程序性能和穩(wěn)定性,實際開發(fā)中我們應(yīng)遵循最佳實踐,合理使用線程調(diào)度相關(guān)的API,通過線程池、同步機制等工具,構(gòu)建出高效、健壯的多線程應(yīng)用程序。
到此這篇關(guān)于Java多線程實現(xiàn)之線程調(diào)度的使用的文章就介紹到這了,更多相關(guān)Java多線程實現(xiàn)線程調(diào)度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java服務(wù)如何調(diào)用系統(tǒng)指令、Bat腳本記錄
這篇文章主要介紹了Java服務(wù)如何調(diào)用系統(tǒng)指令、Bat腳本記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
Idea 解決 Could not autowire. No beans of ''xxxx'' type found
這篇文章主要介紹了Idea 解決 Could not autowire. No beans of 'xxxx' type found 的錯誤提示,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
Java數(shù)據(jù)結(jié)構(gòu)之有效隊列定義與用法示例
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之有效隊列定義與用法,結(jié)合實例形式分析了java有效隊列的數(shù)據(jù)插入、刪除、判斷、計算等相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
java基于雙向環(huán)形鏈表解決丟手帕問題的方法示例
這篇文章主要介紹了java基于雙向環(huán)形鏈表解決丟手帕問題的方法,簡單描述了丟手帕問題,并結(jié)合實例形式給出了Java基于雙向環(huán)形鏈表解決丟手帕問題的步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
javamail發(fā)送附件DataSource使用文件流解決過程
使用ByteArrayDataSource替代傳統(tǒng)附件處理方式,解決James郵件服務(wù)器需通過ApacheHttpClient下載華為云/FTP附件的問題,實現(xiàn)直接內(nèi)存?zhèn)鬏?確保郵件發(fā)送功能正常運作2025-08-08
Java操作Elasticsearch?rest-high-level-client?的基本使用
這篇文章主要介紹了Java操作Elasticsearch?rest-high-level-client?的基本使用,本篇主要講解一下?rest-high-level-client?去操作?Elasticsearch的方法,結(jié)合實例代碼給大家詳細講解,需要的朋友可以參考下2022-10-10

