国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 Java Java基礎 java線程池詳解

java線程池詳解

Nov 26, 2019 pm 03:05 PM
java 線程池

java線程池詳解

線程池概述

1. 線程池就是一個管理線程的池子,可以降低創(chuàng)建和銷毀線程帶來的資源消耗

因為線程其實也是一個對象,創(chuàng)建一個對象,需要經過類加載過程,銷毀一個對象,需要走GC垃圾回收流程,都是需要資源開銷的。

2. 提高響應速度,任務到達了相對于從線程池取線程,自己創(chuàng)建線程肯定慢很多

3. 重復利用,線程用完了再放回池子,達到了重復利用的效果

(推薦視頻:java視頻教程

線程池執(zhí)行

打個比喻

核心線程比作公司正式員工

非核心線程比作外包員工

阻塞隊列比作需求池

提交任務比作提需求

1.jpg

正式執(zhí)行

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,
   BlockingQueue<Runnable> workQueue,
   ThreadFactory threadFactory,
   RejectedExecutionHandler handler)
corePoolSize     核心線程數(shù)
maximumPoolSize  線程池最大線程數(shù)
keepAliveTime    空閑線程存活時間
TimeUnit         線程空閑存活時間單位
workQueue        存放任務的阻塞隊列
threadFactory    線程工廠
handler          飽和策略

● 提交一個任務,線程池里存活的核心線程數(shù)小于線程數(shù)corePoolSize時,線程池會創(chuàng)建一個核心線程去處理提交的任務。

● 如果線程池核心線程數(shù)已滿,即線程數(shù)已經等于corePoolSize,一個新提交的任務,會被放進任務隊列workQueue排隊等待執(zhí)行。

● 當線程池里面存活的線程數(shù)已經等于corePoolSize了,并且任務隊列workQueue也滿,判斷線程數(shù)是否達到maximumPoolSize,即最大線程數(shù)是否已滿,如果沒到達,創(chuàng)建一個非核心線程執(zhí)行提交的任務。

● 如果當前的線程數(shù)達到了maximumPoolSize,還有新的任務過來的話,直接采用拒絕策略處理。

幾種飽和策略

AbortPolicy         拋出一個異常,默認的
DiscardPolicy       直接丟棄任務
DiscardOldestPolicy 丟棄隊列里最老的任務,將當前這個任務繼續(xù)提交給線程池
CallerRunsPolicy    交給線程池調用所在的線程進行處理

線程池異常處理

由于在線程池調用線程處理任務過程中出現(xiàn)的異??赡軙痪€程池捕獲,所以對于任務的執(zhí)行可能是無感知的,因此我們需要考慮線程池異常情況。

方法一:

@Test
public void test1() throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 5; i++) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("name: " + Thread.currentThread().getName());
                    Object a = null;
                    System.out.println(a.hashCode());
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        });
    }
}

方法二:

@Test
public void test2() throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 20; i++) {
        Future<?> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("name: " + Thread.currentThread().getName());
                Object a = null;
                System.out.println(a.hashCode());
            }
        });
        try {
            future.get();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

線程池的工作隊列

● ArrayBlockingQueue

● LinkedBlockingQueue

● SynchronousQueue

● DelayQueue

● PriorityBlockingQueue

==ArrayBlockingQueue==

● 初始化一定容量的數(shù)組

● 使用一個重入鎖,默認使用非公平鎖,入隊和出隊共用一個鎖,互斥

● 是有界設計,如果容量滿無法繼續(xù)添加元素直至有元素被移除

● 使用時開辟一段連續(xù)的內存,如果初始化容量過大容易造成資源浪費,過小易添加失敗

==LinkedBlockingQueue==

● 使用鏈表數(shù)據結構

● 非連續(xù)性內存空間

● 使用兩個重入鎖分別控制元素的入隊和出隊,用Condition進行線程間的喚醒和等待

● 有邊界的,在默認構造方法中容量是Integer.MAX_VALUE

==SynchronousQueue==

● 內部容量是0

● 每次刪除操作都要等待插入操作

● 每次插入操作都要等待刪除操作

● 一個元素,一旦有了插入線程和移除線程,那么很快由插入線程移交給移除線程,這個容器相當于通道,本身不存儲元素

● 在多任務隊列,是最快的處理任務方式。

==PriorityBlockingQueue==

● 無邊界設計,但容量實際是依靠系統(tǒng)資源影響

● 添加元素,如果超過1,則進入優(yōu)先級排序

==DelayQueue==

● 無邊界設計

● 添加(put)不阻塞,移除阻塞

● 元素都有一個過期時間

● 取元素只有過期的才會被取出

常用的線程池

● newFixedThreadPool (固定數(shù)目線程的線程池)

● newCachedThreadPool (可緩存線程的線程池)

● newSingleThreadExecutor (單線程的線程池)

● newScheduledThreadPool (定時及周期執(zhí)行的線程池)

==newFixedThreadPool==

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

特點

1. 核心線程數(shù)和最大線程數(shù)大小一樣

2. 沒有所謂的非空閑時間,即keepAliveTime為0

3. 阻塞隊列為無界隊列LinkedBlockingQueue

工作機制:

2.png

● 提交任務

● 如果線程數(shù)少于核心線程,創(chuàng)建核心線程執(zhí)行任務

● 如果線程數(shù)等于核心線程,把任務添加到LinkedBlockingQueue阻塞隊列

● 如果線程執(zhí)行完任務,去阻塞隊列取任務,繼續(xù)執(zhí)行。

==newCachedThreadPool==

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

線程池特點

● 核心線程數(shù)為0

● 最大線程數(shù)為Integer.MAX_VALUE

● 阻塞隊列是SynchronousQueue

● 非核心線程空閑存活時間為60秒

3.jpg

工作機制:

● 提交任務

● 因為沒有核心線程,所以任務直接加到SynchronousQueue隊列。

● 判斷是否有空閑線程,如果有,就去取出任務執(zhí)行。

● 如果沒有空閑線程,就新建一個線程執(zhí)行。

● 執(zhí)行完任務的線程,還可以存活60秒,如果在這期間,接到任務,可以繼續(xù)活下去;否則,被銷毀。

使用場景

用于并發(fā)執(zhí)行大量短期的小任務。

使用SynchronousQueue作為工作隊列,工作隊列本身并不限制待執(zhí)行的任務的數(shù)量。但此時需要限定線程池的最大大小為一個合理的有限值,而不是Integer.MAX_VALUE,否則可能導致線程池中的工作者線程的數(shù)量一直增加到系統(tǒng)資源所無法承受為止。

如果應用程序確實需要比較大的工作隊列容量,而又想避免無界工作隊列可能導致的問題,不妨考慮SynchronousQueue。SynchronousQueue實現(xiàn)上并不使用緩存空間

==newSingleThreadExecutor==

線程池特點

● 核心線程數(shù)為1

● 最大線程數(shù)也為1

● 阻塞隊列是LinkedBlockingQueue

● keepAliveTime為0

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
}

工作機制

4.png

● 提交任務

● 線程池是否有一條線程在,如果沒有,新建線程執(zhí)行任務

● 如果有,講任務加到阻塞隊列

● 當前的唯一線程,從隊列取任務,執(zhí)行完一個,再繼續(xù)取,一個人(一條線程)夜以繼日地干活。

使用場景

適用于串行執(zhí)行任務的場景,一個任務一個任務的執(zhí)行

==newScheduledThreadPool==

線程池特點

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());
}

●?最大線程數(shù)為Integer.MAX_VALUE

●?阻塞隊列是DelayedWorkQueue

●?keepAliveTime為0

●?scheduleAtFixedRate() :按某種速率周期執(zhí)行

●?scheduleWithFixedDelay():在某個延遲后執(zhí)行

工作機制

●?添加一個任務

●?線程池中的線程從 DelayQueue 中取任務

●?線程從 DelayQueue 中獲取 time 大于等于當前時間的task

●?執(zhí)行完后修改這個 task 的 time 為下次被執(zhí)行的時間

●?這個 task 放回DelayQueue隊列中

scheduleWithFixedDelay

●?無論任務執(zhí)行時間長短,都是當?shù)谝粋€任務執(zhí)行完成之后,延遲指定時間再開始執(zhí)行第二個任務

scheduleAtFixedRate

●?在任務執(zhí)行時間小于間隔時間的情況下,程序以起始時間為準則,每隔指定時間執(zhí)行一次,不受任務執(zhí)行時間影響

●?當執(zhí)行任務時間大于間隔時間,此方法不會重新開啟一個新的任務進行執(zhí)行,而是等待原有任務執(zhí)行完成,馬上開啟下一個任務進行執(zhí)行。此時,執(zhí)行間隔時間已經被打亂

本文來自php中文網,java教程欄目,歡迎學習!

以上是java線程池詳解的詳細內容。更多信息請關注PHP中文網其他相關文章!

本站聲明
本文內容由網友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權的內容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務,必須先關閉自動提交模式,再執(zhí)行多個操作,最后根據結果提交或回滾;1.調用conn.setAutoCommit(false)以開始事務;2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調用conn.commit(),若發(fā)生異常則調用conn.rollback()確保數(shù)據一致性;同時應使用try-with-resources管理資源,妥善處理異常并關閉連接,避免連接泄漏;此外建議使用連接池、設置保存點實現(xiàn)部分回滾,并保持事務盡可能短以提升性能。

如何使用Java的日歷? 如何使用Java的日歷? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

比較Java框架:Spring Boot vs Quarkus vs Micronaut 比較Java框架:Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

了解網絡端口和防火墻 了解網絡端口和防火墻 Aug 01, 2025 am 06:40 AM

NetworkPortSandFireWallsworkTogetHertoEnableCommunication whereSeringSecurity.1.NetWorkPortSareVirtualendPointSnumbered0-655 35,with-Well-with-Newonportslike80(HTTP),443(https),22(SSH)和25(smtp)sindiessingspefificservices.2.portsoperateervertcp(可靠,c

垃圾收集如何在Java工作? 垃圾收集如何在Java工作? Aug 02, 2025 pm 01:55 PM

Java的垃圾回收(GC)是自動管理內存的機制,通過回收不可達對象釋放堆內存,減少內存泄漏風險。1.GC從根對象(如棧變量、活動線程、靜態(tài)字段等)出發(fā)判斷對象可達性,無法到達的對象被標記為垃圾。2.基于標記-清除算法,標記所有可達對象,清除未標記對象。3.采用分代收集策略:新生代(Eden、S0、S1)頻繁執(zhí)行MinorGC;老年代執(zhí)行較少但耗時較長的MajorGC;Metaspace存儲類元數(shù)據。4.JVM提供多種GC器:SerialGC適用于小型應用;ParallelGC提升吞吐量;CMS降

使用HTML'輸入類型”作為用戶數(shù)據 使用HTML'輸入類型”作為用戶數(shù)據 Aug 03, 2025 am 11:07 AM

選擇合適的HTMLinput類型能提升數(shù)據準確性、增強用戶體驗并提高可用性。1.根據數(shù)據類型選用對應input類型,如text、email、tel、number和date,可實現(xiàn)自動校驗和適配鍵盤;2.利用HTML5新增類型如url、color、range和search,可提供更直觀的交互方式;3.配合使用placeholder和required屬性,可提升表單填寫效率和正確率,但需注意placeholder不能替代label。

比較Java構建工具:Maven vs. Gradle 比較Java構建工具:Maven vs. Gradle Aug 03, 2025 pm 01:36 PM

Gradleisthebetterchoiceformostnewprojectsduetoitssuperiorflexibility,performance,andmoderntoolingsupport.1.Gradle’sGroovy/KotlinDSLismoreconciseandexpressivethanMaven’sverboseXML.2.GradleoutperformsMaveninbuildspeedwithincrementalcompilation,buildcac

以身作則,解釋說明 以身作則,解釋說明 Aug 02, 2025 am 06:26 AM

defer用于在函數(shù)返回前執(zhí)行指定操作,如清理資源;參數(shù)在defer時立即求值,函數(shù)按后進先出(LIFO)順序執(zhí)行;1.多個defer按聲明逆序執(zhí)行;2.常用于文件關閉等安全清理;3.可修改命名返回值;4.即使發(fā)生panic也會執(zhí)行,適合用于recover;5.避免在循環(huán)中濫用defer,防止資源泄漏;正確使用可提升代碼安全性和可讀性。

See all articles