java中的異步加載new Thread()方式
java的異步加載new Thread()
public class LoginInterface{ ? ?public String delSession(){ ? ? new Thread(new Runnable() { @Override public void run() { //需要執(zhí)行的代碼 } }).start(); ? ?}}
使用匿名內(nèi)部類編譯
class LoginInterface$1 ? implements Runnable { ? LoginInterface$1(LoginInterface paramLoginInterface, String paramString) ? { ? } ? public void run() ? { //要執(zhí)行的代碼 ? } }
聊聊new Thread()的危害
危害
1)開銷大
每次new Thread() 都會創(chuàng)建新的對象,開銷較大,無法復(fù)用增加垃圾回收的負(fù)擔(dān)。
2)管理困難
每個(gè)new Thread() 都是獨(dú)立的個(gè)體,無法有效的管控,無限制創(chuàng)建相互競爭,可能導(dǎo)致oom或者核心業(yè)務(wù)線程阻塞。
3)功能單一
無法定時(shí)執(zhí)行,中斷線程等功能。
線程池
1)復(fù)用已創(chuàng)建的線程,減少對象創(chuàng)建、消亡的開銷,性能佳。
2)可控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時(shí)避免過多資源競爭,避免堵塞。
3)可定時(shí)執(zhí)行、中斷線程等功能。
線程池大小
1)CPU密集型(計(jì)算型)
- 使用較小的線程池,一般是Cpu核心數(shù)+1
- 因?yàn)镃PU密集型任務(wù)CPU的使用率很高,若開過多的線程,只能增加線程上下文的切換次數(shù),帶來額外的開銷
2)IO密集型(查詢訪問型)
- 使用較大的線程池,一般CPU核心數(shù) * 2
- 因?yàn)镮O密集型CPU使用率不高,可以讓CPU等待IO的時(shí)候處理別的任務(wù),充分利用cpu時(shí)間
線程池創(chuàng)建【使用ThreadPoolExecutor手動(dòng)創(chuàng)建】
public class CommonThreadPool { /** * 線程池對象 */ public static ExecutorService pool = null; /** * 線程池核心池的大小 */ private static final int CORE_POOL_SIZE = 5; /** * 獲取當(dāng)前系統(tǒng)的CPU 數(shù)目 */ private static int cpuNums = Runtime.getRuntime().availableProcessors(); /** * 線程池的最大線程數(shù) */ private static final int MAX_POOL_SIZE = (cpuNums * 2) > CORE_POOL_SIZE ? (cpuNums * 2) : CORE_POOL_SIZE; static { pool = new ThreadPoolExecutor( CORE_POOL_SIZE, // 核心線程數(shù) MAX_POOL_SIZE, // 最大線程數(shù) 通常核心線程數(shù)=最大線程數(shù) 當(dāng)MAX_POOL_SIZE > CORE_POOL_SIZE 時(shí),并不是當(dāng)核心線程全部被占用后立馬開始創(chuàng)建新的線程(只有在隊(duì)列也滿了之后才會開始新建線程) 0L, // 存活時(shí)間 >=0 0 永不回收【非核心線程除外】 TimeUnit.MILLISECONDS, // 單位 new ArrayBlockingQueue<Runnable>(100), // 隊(duì)列 存放待執(zhí)行任務(wù) new ThreadFactoryBuilder().setNameFormat("CommonThread-%d").build(), // 創(chuàng)建工廠 new ThreadPoolExecutor.AbortPolicy()); // 拒絕策略 默認(rèn)拒絕 丟棄 丟棄最老的 主線程執(zhí)行 } }
禁用Executors創(chuàng)建線程池
1)Executors屏蔽的線程池的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),開發(fā)人員需要根據(jù)服務(wù)器情況與業(yè)務(wù)場景定義更合適的線程池。
2)newFixedThreadPool 和 newSingleThreadExecutor的主要問題是堆積的請求處理隊(duì)列可能會耗費(fèi)非常大的內(nèi)存,甚至 OOM。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
3)newCachedThreadPool 和 newScheduledThreadPool:主要問題是線程數(shù)最大數(shù)是 Integer.MAX_VALUE,可能會創(chuàng)建數(shù)量非常多的線程,甚至 OOM。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
- LinkedBlockingQueue:隊(duì)列默認(rèn)大小Integer.MAX_VALUE,未指定大小時(shí)可以視為無界隊(duì)列。
- SynchronousQueue:隊(duì)列大容量為0,不存儲任何數(shù)據(jù)。
- DelayedWorkQueue:無界,隊(duì)列順序按照延時(shí)時(shí)長排序。
任務(wù)執(zhí)行流程
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
feign調(diào)用第三方接口,編碼定義GBK,響應(yīng)中文亂碼處理方式
這篇文章主要介紹了feign調(diào)用第三方接口,編碼定義GBK,響應(yīng)中文亂碼處理方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01通過web控制當(dāng)前的SpringBoot程序重新啟動(dòng)
本文主要給大家介紹了如何通過web控制當(dāng)前的SpringBoot程序重新啟動(dòng),文章給出了詳細(xì)的代碼示例供大家參考,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-11-11springboot+redis+阿里云短信實(shí)現(xiàn)手機(jī)號登錄功能
這篇文章主要介紹了springboot+redis+阿里云短信實(shí)現(xiàn)手機(jī)號登錄功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01Spring Bean生命周期之Bean的實(shí)例化詳解
這篇文章主要為大家詳細(xì)介紹了Spring Bean生命周期之Bean的實(shí)例化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03