国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java并發(fā)編程之線程池詳解

這篇具有很好參考價(jià)值的文章主要介紹了Java并發(fā)編程之線程池詳解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

??今日良言:不悲傷 不彷徨 有風(fēng)聽風(fēng) 有雨看雨

??一、簡介

??二、相關(guān)代碼

??1.線程池代碼

??2.自定義實(shí)現(xiàn)線程池

??三、ThreadPoolExecutor類


??今日良言:不悲傷 不彷徨 有風(fēng)聽風(fēng) 有雨看雨

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

??一、簡介

首先來介紹一下什么是線程池,線程池是一種利用池化技術(shù)思想來實(shí)現(xiàn)的線程管理技術(shù),主要是為了復(fù)用線程、便利地管理線程和任務(wù)并將線程的創(chuàng)建和任務(wù)的執(zhí)行解耦開來。我們可以創(chuàng)建線程池來復(fù)用已經(jīng)創(chuàng)建的線程來降低頻繁創(chuàng)建和銷毀線程所帶來的資源消耗。在JAVA中主要是通過java.util.concurrent包中的ThreadPoolExecutor類來實(shí)現(xiàn)線程池 。

??二、相關(guān)代碼

??1.線程池代碼

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

這里就是創(chuàng)造出一個(gè)10個(gè)線程的線程池,然后就可以隨機(jī)安排這些線程完成任務(wù)了。

線程池提供了一個(gè)重要的方法 submit 可以給線程池提交若干個(gè)任務(wù)。

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

?submit的參數(shù)是一個(gè)Runnable,用來描述這些線程要執(zhí)行的任務(wù)是什么。

線程池中的線程都是前臺(tái)線程,前臺(tái)線程會(huì)阻止進(jìn)程結(jié)束,也就是說,運(yùn)行程序之后,main線程結(jié)束了,但是整個(gè)進(jìn)程沒有結(jié)束。

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

當(dāng)前是往線程池里放了 1000 個(gè)任務(wù),1000 個(gè)任務(wù)就是由這 10 個(gè)線程來平均分配一下,差不多是一人執(zhí)行 100個(gè),但是這里并非是嚴(yán)格的平均,可能有的多一個(gè)有的少一個(gè)都正常。(每個(gè)線程都執(zhí)行完一個(gè)任務(wù)之后,再立即取下一個(gè)任務(wù)...由于每個(gè)任務(wù)執(zhí)行時(shí)間都差不多,因此每個(gè)線程做的任務(wù)數(shù)量就差不多)

上述代碼涉及到變量捕獲

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

?這里的 i 是主線程里的局部變量(在主線程的棧上),隨著主線程的代碼執(zhí)行結(jié)束就銷毀了,但是,很可能這里的 for 循環(huán)已經(jīng)執(zhí)行完了,當(dāng)前 run 的任務(wù)在線程池里還沒有排到,此時(shí) i 就已經(jīng)要銷毀了。這里的 run 方法屬于 Runnable ,這個(gè)方法的執(zhí)行時(shí)機(jī)并不是立刻執(zhí)行,而是在未來的某個(gè)時(shí)間點(diǎn)(后續(xù)在線程池的隊(duì)列中排到了) 才會(huì)執(zhí)行,為了避免作用域的差異,導(dǎo)致執(zhí)行 run 方法的時(shí)候,i 已經(jīng)銷毀了,于是就有了變量捕獲,也就是讓 run 方法把主線程的 i 往當(dāng)前 run 方法的棧上拷貝一份(在定義 run 方法的時(shí)候了,把當(dāng)前 i 的值記住,后續(xù)執(zhí)行 run 的時(shí)候,就創(chuàng)建一個(gè)也叫做 i 的局部變量,并且把這個(gè)值給賦值過去)。

在Java 中,對(duì)于變量捕獲,做了一些額外的要求,在JDK 1.8之前,要求變量捕獲只能捕獲 final 修飾的變量,后來發(fā)現(xiàn),這樣太麻煩了,于是,在 JDK 1.8 開始,發(fā)送了一點(diǎn)標(biāo)準(zhǔn),要求不一定非得待 final 關(guān)鍵字,只要代碼中沒有修改過這個(gè)變量,也可以捕獲。

在上述代碼中,i 是被修改的,因此不能捕獲,但是 n 沒有被修改,所以可以被捕獲。

接下來,介紹一下幾種不同的線程池:

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

new FixedThreadPool? ? ? ? 創(chuàng)建固定線程數(shù)的線程池。

newCachedThreadPool? ? ? 線程數(shù)量是動(dòng)態(tài)變化的,任務(wù)多了就多創(chuàng)建幾個(gè)線程,任務(wù)少了?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 就少創(chuàng)建幾個(gè)。

newScheduledThreadPool? 類似于定時(shí)器,讓任務(wù)延時(shí)執(zhí)行。

newSingleThreadExecutor? 線程池里只有一個(gè)線程。

上述這些線程池,本質(zhì)上都是通過包裝 ThreadPoolExecutor 來實(shí)現(xiàn)的,這個(gè)線程池用起來比較麻煩,所以提供了工廠類,讓我們使用更方便,ThreadPoolExecutor 提供的功能更為強(qiáng)大,后面會(huì)詳細(xì)介紹。?

??2.自定義實(shí)現(xiàn)線程池

?自定義實(shí)現(xiàn)線程池代碼如下:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class MyThreadPool {
    // 阻塞隊(duì)列
    private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
    // 若干個(gè)工作線程
    // n表示線程的數(shù)量
    public MyThreadPool(int n) {
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        // 從阻塞隊(duì)列中取出然后執(zhí)行
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            t.start();
        }
    }
    // 注冊(cè)任務(wù)給線程池
    public void submit(Runnable runnable) {
        try {
            queue.put(runnable);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
public class Exercise{
    public static void main(String[] args) {
        MyThreadPool myThreadPool = new MyThreadPool(10);
        for (int i = 0; i < 1000; i++) {
            int n = i;
            myThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello:"+n);
                }
            });
        }
    }
}

??三、ThreadPoolExecutor類

最后,介紹一下ThreadPoolExecutor 里面的參數(shù),如下圖:

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

1)int corePoolSize

核心線程數(shù)

2)int maximumPoolSize

最大線程數(shù)

ThreadPoolExecutor 相當(dāng)于是把里面的線程分成了兩類,一類是核心線程,一類是臨時(shí)線程,核心線程相當(dāng)于是正式工,臨時(shí)線程相當(dāng)于是臨時(shí)工,這二者之和就是最大線程數(shù)。

如果任務(wù)多,需要?jiǎng)?chuàng)建更多的線程,但是,一個(gè)程序的任務(wù)不一定始終都有很多,有時(shí)候多,有時(shí)候少,如果現(xiàn)在任務(wù)少了,線程還那么多,就非常不合適了,因此,就需要對(duì)現(xiàn)有的線程進(jìn)行一定的淘汰,整體的淘汰策略是:核心線程保底,臨時(shí)線程動(dòng)態(tài)調(diào)節(jié)。

在實(shí)際開發(fā)的時(shí)候,線程池的線程數(shù)設(shè)置成多少比較合適呢?

實(shí)際上,這里不應(yīng)該回答出具體的數(shù)字,在實(shí)際開發(fā)中,線程池的線程數(shù)設(shè)置需要根據(jù)具體情況進(jìn)行調(diào)整,一般來說,應(yīng)該設(shè)置為CPU核心數(shù)的兩倍到四倍之間,如果線程數(shù)過少,則導(dǎo)致任務(wù)等待時(shí)間過長,而如果線程數(shù)過多,會(huì)導(dǎo)致系統(tǒng)資源浪費(fèi)。如果任務(wù)是IO密集型的,那么可以適當(dāng)?shù)脑黾泳€程數(shù),如果任務(wù)是CPU密集型的,則可以適當(dāng)?shù)臏p少線程數(shù)。

3)long?keepAliveTime

臨時(shí)線程的最大空閑時(shí)間,超出這個(gè)時(shí)間,臨時(shí)線程就會(huì)被銷毀了。

也就是臨時(shí)工的最大摸魚時(shí)間。

4)TimeUnit unit?

時(shí)間單位(s,ms,分鐘...)

5)BlockingQueue<Runnable>?workQueue

線程池的任務(wù)隊(duì)列

此處使用的是阻塞隊(duì)列,每個(gè)線程都是在不停的嘗試take,如果有任務(wù),就take成功,沒有就阻塞。

6)ThreadFactory? threadFactory

用于創(chuàng)建線程,線程池是需要?jiǎng)?chuàng)建線程的

7)RejectedExecutionHandler handler

描述了線程池的“拒絕策略”,也是一個(gè)特殊的對(duì)象,描述了當(dāng)線程池任務(wù)隊(duì)列滿了,如果繼續(xù)添加任務(wù)會(huì)有什么樣的行為。

標(biāo)準(zhǔn)庫提供了四個(gè)拒絕策略,如下圖:

Java并發(fā)編程之線程池詳解,java,開發(fā)語言

?第一個(gè)拒絕策略

如果任務(wù)太多,任務(wù)隊(duì)列滿了,就直接拋出異常。

第二個(gè)拒絕策略

如果任務(wù)太多,任務(wù)隊(duì)列滿了,多出來的任務(wù),誰加的誰負(fù)責(zé)執(zhí)行。

第三個(gè)拒絕策略

如果任務(wù)太多,任務(wù)隊(duì)列滿了,丟棄最早的任務(wù)。

第四個(gè)拒絕策略

如果任務(wù)太多,任務(wù)隊(duì)列滿了,丟棄最新的任務(wù)。


?以上就是本篇博客的所有內(nèi)容了,望有所幫助~文章來源地址http://www.zghlxwxcb.cn/news/detail-663671.html

到了這里,關(guān)于Java并發(fā)編程之線程池詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護(hù)線程

    【Java 并發(fā)編程】一文讀懂線程、協(xié)程、守護(hù)線程

    在 Java 線程的生命周期一文中提到了 就緒狀態(tài)的線程在獲得 CPU 時(shí)間片后變?yōu)檫\(yùn)行中狀態(tài) ,否則就會(huì)在 可運(yùn)行狀態(tài) 或者 阻塞狀態(tài) ,那么系統(tǒng)是如何分配線程時(shí)間片以及實(shí)現(xiàn)線程的調(diào)度的呢?下面我們就來講講線程的調(diào)度策略。 線程調(diào)度是指系統(tǒng)為線程分配 CPU 執(zhí)行時(shí)間片

    2023年04月08日
    瀏覽(24)
  • 【Java并發(fā)編程】變量的線程安全分析

    【Java并發(fā)編程】變量的線程安全分析

    1.成員變量和靜態(tài)變量是否線程安全? 如果他們沒有共享,則線程安全 如果被共享: 只有讀操作,則線程安全 有寫操作,則這段代碼是臨界區(qū),需要考慮線程安全 2.局部變量是否線程安全 局部變量是線程安全的 當(dāng)局部變量引用的對(duì)象則未必 如果給i對(duì)象沒有逃離方法的作用

    2024年02月08日
    瀏覽(90)
  • Java面試_并發(fā)編程_線程基礎(chǔ)

    Java面試_并發(fā)編程_線程基礎(chǔ)

    進(jìn)程是正在運(yùn)行程序的實(shí)例, 進(jìn)程中包含了線程, 每個(gè)線程執(zhí)行不同的任務(wù) 不同的進(jìn)程使用不同的內(nèi)存空間, 在當(dāng)前進(jìn)程下的所有線程可以共享內(nèi)存空間 線程更輕量, 線程上下文切換成本一般上要比進(jìn)程上下文切換低(上下文切換指的是從一個(gè)線程切換到另一個(gè)線程) 并發(fā)是單個(gè)

    2024年02月07日
    瀏覽(30)
  • 【Java并發(fā)編程】線程中斷機(jī)制(輔以常見案例)

    本文由淺入深介紹了中斷機(jī)制、中斷的常見案例和使用場景。 因?yàn)橐恍┰蛐枰∠菊趫?zhí)行的線程。我們舉幾個(gè)栗子: 假設(shè)踢足球點(diǎn)球時(shí),A隊(duì)前4輪中了4個(gè)球,B隊(duì)前4輪只中了2個(gè)球,此時(shí)勝負(fù)已分,第5輪這個(gè)點(diǎn)球就不用踢了,此時(shí)需要停止A隊(duì)的線程和B隊(duì)的線程(共

    2024年02月13日
    瀏覽(30)
  • java并發(fā)編程:多線程基礎(chǔ)知識(shí)介紹

    最初的計(jì)算機(jī)只能接受一些特定的指令,用戶每輸入一個(gè)指令,計(jì)算機(jī)就做出一個(gè)操作。當(dāng)用戶在思考或者輸入時(shí),計(jì)算機(jī)就在等待。這樣效率非常低下,在很多時(shí)候,計(jì)算機(jī)都處在等待狀態(tài)。 后來有了 批處理操作系統(tǒng) ,把一系列需要操作的指令寫下來,形成一個(gè)清單,一次

    2024年02月07日
    瀏覽(21)
  • Java并發(fā)編程學(xué)習(xí)18-線程池的使用(下)

    上篇介紹了 ThreadPoolExecutor 配置和擴(kuò)展相關(guān)的信息,本篇開始將介紹遞歸算法的并行化。 還記得我們?cè)凇禞ava并發(fā)編程學(xué)習(xí)11-任務(wù)執(zhí)行演示》中,對(duì)頁面繪制程序進(jìn)行一系列改進(jìn),這些改進(jìn)大大地提供了頁面繪制的并行性。 我們簡單回顧下相關(guān)的改進(jìn)過程: 第一次新增時(shí),頁

    2024年02月12日
    瀏覽(24)
  • Java并發(fā)編程學(xué)習(xí)16-線程池的使用(中)

    Java并發(fā)編程學(xué)習(xí)16-線程池的使用(中)

    上篇分析了在使用任務(wù)執(zhí)行框架時(shí)需要注意的各種情況,并簡單介紹了如何正確調(diào)整線程池大小。 本篇將繼續(xù)介紹對(duì)線程池進(jìn)行配置與調(diào)優(yōu)的一些方法,詳細(xì)如下: ThreadPoolExecutor 為 Executors 中的 newCachedThreadPool 、 newFixedThreadPool 和 newScheduledThreadExecutor 等工廠方法返回的 Exe

    2024年02月10日
    瀏覽(18)
  • Java并發(fā)編程學(xué)習(xí)筆記(一)線程的入門與創(chuàng)建

    Java并發(fā)編程學(xué)習(xí)筆記(一)線程的入門與創(chuàng)建

    認(rèn)識(shí) 程序由指令和數(shù)據(jù)組成,簡單來說,進(jìn)程可以視為程序的一個(gè)實(shí)例 大部分程序可以同時(shí)運(yùn)行多個(gè)實(shí)例進(jìn)程,例如記事本、畫圖、瀏覽器等 少部分程序只能同時(shí)運(yùn)行一個(gè)實(shí)例進(jìn)程,例如QQ音樂、網(wǎng)易云音樂等 一個(gè)進(jìn)程可以分為多個(gè)線程,線程為最小調(diào)度單位,進(jìn)程則是作

    2024年02月16日
    瀏覽(46)
  • Java并發(fā)編程(三)線程同步 上[synchronized/volatile]

    Java并發(fā)編程(三)線程同步 上[synchronized/volatile]

    當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),將會(huì)導(dǎo)致數(shù)據(jù)不準(zhǔn)確,相互之間產(chǎn)生沖突,非常容易出現(xiàn)線程安全問題,比如多個(gè)線程都在操作同一數(shù)據(jù),都打算修改商品庫存,這樣就會(huì)導(dǎo)致數(shù)據(jù)不一致的問題。 所以我們通過線程同步機(jī)制來保證線程安全,加入同步鎖以避免在該線程沒有完成

    2024年02月13日
    瀏覽(28)
  • 【Java|多線程與高并發(fā)】線程池詳解

    【Java|多線程與高并發(fā)】線程池詳解

    Java線程池是一種用于管理和重用線程的機(jī)制,它可以在需要執(zhí)行任務(wù)時(shí),從線程池中獲取線程,執(zhí)行任務(wù),然后將線程放回池中,以便后續(xù)使用。線程池可以有效地管理線程的數(shù)量,提高程序的性能和資源利用率。 為什么從線程池里面取線程比直接創(chuàng)建線程快呢? 創(chuàng)建線程是

    2024年02月11日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包