Java中的線程池

阻塞隊(duì)列

隊(duì)列:先進(jìn)先出的一種數(shù)據(jù)結(jié)構(gòu)
阻塞隊(duì)列就是在數(shù)據(jù)為空的時(shí)候动看,如果從隊(duì)列中獲取數(shù)據(jù)將被阻塞,如果隊(duì)列滿了的話往隊(duì)列里面插入數(shù)據(jù)將會被阻塞洞慎。

有界與無界

有界隊(duì)列就是隊(duì)列的大小是固定的
無界隊(duì)列就是隊(duì)列滿了之后可以進(jìn)行擴(kuò)容

延時(shí)阻塞隊(duì)列

DelayQueue,延時(shí)獲取痛单,如果延時(shí)沒有到,那么將會被阻塞
可以

線程池的參數(shù)

核心線程數(shù)

最大線程數(shù)

  1. IO密集型
    IO密集型一般最大線程數(shù)是cpu核心數(shù)2
    IO密集型一般不是特別占用cpu的資源劲腿,有網(wǎng)絡(luò)操作和磁盤操作旭绒。當(dāng)進(jìn)行一個(gè)網(wǎng)絡(luò)操作的時(shí)候,線程需要等待網(wǎng)絡(luò)數(shù)據(jù)的返回谆棱,這個(gè)時(shí)候線程會交出執(zhí)行權(quán)快压,所以我們設(shè)置cpu核心數(shù)
    2的話會保證cpu的資源不會被浪費(fèi)。
  2. CPU密集型
    CPU密集型一般最大線程數(shù)是cpu核心數(shù)+1
    CPU密集型一般是頻繁的數(shù)據(jù)操作垃瞧,操作系統(tǒng)中有內(nèi)存和磁盤存儲蔫劣,操作系統(tǒng)將磁盤存儲的一部分拿出來作為虛擬內(nèi)存,如果一個(gè)線程要使用虛擬內(nèi)存和內(nèi)存中的數(shù)據(jù)的時(shí)候个从,由于虛擬內(nèi)存獲取數(shù)據(jù)的速度遠(yuǎn)遠(yuǎn)沒有從內(nèi)存獲取數(shù)據(jù)快脉幢,這個(gè)時(shí)候我們就可以再啟動(dòng)額外的線程來執(zhí)行下一個(gè)數(shù)據(jù)操作。
  3. 混合型
    如果CPU密集型和IO密集型花的時(shí)間差不多嗦锐,那么可以進(jìn)行拆分為2個(gè)線程池
    如果差距很大的話嫌松,以時(shí)間花費(fèi)大的為準(zhǔn)

線程存活時(shí)間

一般來說當(dāng)線程的run方法執(zhí)行完了之后線程就會被銷毀,那么如何讓線程按照存活時(shí)間奕污?
我們從阻塞隊(duì)列中獲取數(shù)據(jù)萎羔,如果沒有數(shù)據(jù)線程會被阻塞,他就不會死亡

拒絕策略

當(dāng)核心線程數(shù)碳默,阻塞隊(duì)列贾陷,最大線程數(shù)已滿的話線程池有拒絕任務(wù)的策略
1.拋異常
立馬拋出一場
2.拋棄阻塞隊(duì)列最前面的
刪除掉隊(duì)列中最老的那一個(gè)任務(wù)
3.拋棄現(xiàn)有的任務(wù)
直接把現(xiàn)在要提交的任務(wù)刪掉
4.交給提交任務(wù)的線程處理
如果主線程提交的任務(wù),那么就讓主線程來執(zhí)行嘱根。

線程池關(guān)閉

shutDown 將還未執(zhí)行的線程銷毀
shutDownNow 使用中斷策略interrupt髓废,銷毀執(zhí)行中的線程以及未執(zhí)行的線程

線程池的原理

1.當(dāng)線程池中的線程還沒有達(dá)到核心線程數(shù),那么就創(chuàng)建線程來執(zhí)行任務(wù)
2.如果線程池中的線程還沒有達(dá)到核心線程數(shù)该抒,那么就向阻塞隊(duì)列中插入
3.如果阻塞隊(duì)列也滿了慌洪,那么就看看是否達(dá)到最大線程數(shù),如果沒有達(dá)到最大線程數(shù),那就開啟線程執(zhí)行任務(wù)
4.如果達(dá)到了最大線程數(shù)冈爹,那么就使用拒絕策略

零拷貝

用戶空間和內(nèi)核空間的概念
為了保證我們的應(yīng)用程序訪問不到操作系統(tǒng)里面的數(shù)據(jù)涌攻,并且不篡改操作系統(tǒng)的數(shù)據(jù),操作系統(tǒng)將內(nèi)存分為了2部分频伤,一部分是操作系統(tǒng)內(nèi)存癣漆,一部分是用戶內(nèi)存,用戶內(nèi)存無法訪問操作系統(tǒng)內(nèi)存剂买。
但是,如果我們程序需要訪問網(wǎng)絡(luò)的時(shí)候癌蓖,需要操作系統(tǒng)底層調(diào)用網(wǎng)卡等設(shè)備瞬哼,我們需要在用戶空間里面將請求參數(shù)復(fù)制到操作系統(tǒng)內(nèi)存中,當(dāng)獲取到網(wǎng)絡(luò)結(jié)果之后需要將返回?cái)?shù)據(jù)從操作系統(tǒng)內(nèi)存拷貝到用戶內(nèi)存中
為了避免兩次無用的拷貝租副,操作系統(tǒng)允許我們的應(yīng)用程序在操作系統(tǒng)內(nèi)存中申請一塊臨時(shí)空間坐慰,我們只需要將請求數(shù)據(jù)放到申請的操作系統(tǒng)空間內(nèi),當(dāng)網(wǎng)絡(luò)數(shù)據(jù)返回的時(shí)候會寫入到我們申請的空間內(nèi)用僧。

DMA

磁盤操作 操作系統(tǒng)會交給磁盤控制器
網(wǎng)絡(luò)操作 操作系統(tǒng)會交給網(wǎng)絡(luò)控制器

單機(jī)緩存系統(tǒng)

1.通過add和get方法存入和獲取數(shù)據(jù)结胀,當(dāng)add的時(shí)候數(shù)據(jù)也要放入延時(shí)隊(duì)列中。
2.開啟一個(gè)子線程獲取延時(shí)隊(duì)列的數(shù)據(jù)责循,如果拿到數(shù)據(jù)了說明時(shí)間到了糟港,過期了我們就需要將數(shù)據(jù)刪除,如果沒有拿到說明還未過期

public class Memory {

    private DelayQueue<Data> delayQueue;

    private ConcurrentHashMap<String,Object> hashMap=new ConcurrentHashMap<>();
    private final Thread thread;

    private Memory(){
        delayQueue=new DelayQueue<>();

        thread = new Thread(new CheckRunnable(this));
        thread.start();
    }

    private static Memory memory;


    public static Memory getInstance(){
        if (memory==null){
            synchronized (Memory.class){
                if (memory==null){
                    memory=new Memory();
                }
            }
        }
        return memory;
    }

    public <T>T get(String key){
        return (T) hashMap.get(key);
    }


    public <T> void add(String key,T value,long time){
        delayQueue.add(new Data(key,time));

        hashMap.put(key,value);
    }

    static class CheckRunnable implements Runnable{
        private Memory memory;

        public CheckRunnable(Memory memory){
            this.memory=memory;
        }

        @Override
        public void run() {
            Thread thread = Thread.currentThread();
            while (!thread.isInterrupted()){
                Data take = memory.delayQueue.poll();
                if (take!=null) {
                    if (memory.hashMap.containsKey(take.getKey())) {
                        System.out.println("remove");
                        memory.hashMap.remove(take.getKey());
                    }
                }
            }
        }
    }

    public void shutDown(){
        thread.interrupt();
        hashMap.clear();
    }


    public static void main(String[] args) {



        new Thread(){
            @Override
            public void run() {
                super.run();
                final Memory instance = Memory.getInstance();
                instance.<String>add("name","Z",10000);

                instance.<Integer>add("age",18,8000);
                int count=1;
                while (true){
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(2000*count);
                    String name = instance.<String>get("name");

                    Integer age = instance.<Integer>get("age");

                    System.out.println("name="+name);
                    System.out.println("age="+age);
                    count++;
                }
            }
        }.start();
    }

}

public class Data implements Delayed {

    private String key;
    private long time;

    public Data(String key, long timeout){
        this.time=timeout+System.currentTimeMillis();
        this.key=key;
    }

    public String getKey(){
        return key;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        return this.time-System.currentTimeMillis();
    }

    @Override
    public int compareTo(Delayed o) {

        if (this.getDelay(TimeUnit.MILLISECONDS)>o.getDelay(TimeUnit.MILLISECONDS)){
            return 1;
        }else if (this.getDelay(TimeUnit.MILLISECONDS)<o.getDelay(TimeUnit.MILLISECONDS)){
            return -1;
        }
        return 0;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末院仿,一起剝皮案震驚了整個(gè)濱河市秸抚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歹垫,老刑警劉巖剥汤,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件排惨,死亡現(xiàn)場離奇詭異吭敢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)暮芭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門蠢沿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舷蟀,“玉大人扫步,你說我怎么就攤上這事⌒僮樱” “怎么了河胎?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虎敦。 經(jīng)常有香客問我游岳,道長,這世上最難降的妖魔是什么其徙? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任胚迫,我火速辦了婚禮,結(jié)果婚禮上唾那,老公的妹妹穿的比我還像新娘访锻。我一直安慰自己,他們只是感情好闹获,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布期犬。 她就那樣靜靜地躺著,像睡著了一般避诽。 火紅的嫁衣襯著肌膚如雪龟虎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天沙庐,我揣著相機(jī)與錄音遣总,去河邊找鬼。 笑死轨功,一個(gè)胖子當(dāng)著我的面吹牛旭斥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播古涧,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼垂券,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羡滑?” 一聲冷哼從身側(cè)響起菇爪,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柒昏,沒想到半個(gè)月后凳宙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡职祷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年氏涩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了届囚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡是尖,死狀恐怖意系,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情饺汹,我是刑警寧澤蛔添,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站兜辞,受9級特大地震影響迎瞧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逸吵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一夹攒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胁塞,春花似錦、人聲如沸压语。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胎食。三九已至扰才,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厕怜,已是汗流浹背衩匣。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粥航,地道東北人琅捏。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像递雀,于是被迫代替她去往敵國和親柄延。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344