最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java利用線(xiàn)程工廠(chǎng)監(jiān)控線(xiàn)程池的實(shí)現(xiàn)示例

 更新時(shí)間:2021年04月12日 14:09:09   作者:炒燜煎糖板栗  
這篇文章主要介紹了Java利用線(xiàn)程工廠(chǎng)監(jiān)控線(xiàn)程池的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

ThreadFactory

線(xiàn)程池中的線(xiàn)程從哪里來(lái)呢?就是ThreadFoctory

public interface ThreadFactory {
    Thread newThread(Runnable r);
}

Threadfactory里面有個(gè)接口,當(dāng)線(xiàn)程池中需要?jiǎng)?chuàng)建線(xiàn)程就會(huì)調(diào)用該方法,也可以自定義線(xiàn)程工廠(chǎng)

public class ThreadfactoryText {
    public static void main(String[] args) {
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                int num=new Random().nextInt(10);
                System.out.println(Thread.currentThread().getId()+"--"+System.currentTimeMillis()+"--睡眠"+num);
                try {
                    TimeUnit.SECONDS.sleep(num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //創(chuàng)建線(xiàn)程池 使用自定義線(xiàn)程工廠(chǎng) 采用默認(rèn)的拒絕策略
        ExecutorService executorService=new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t=new Thread(r);
                t.setDaemon(true);//設(shè)置為守護(hù)線(xiàn)程,當(dāng)主線(xiàn)程運(yùn)行結(jié)束,線(xiàn)程池中線(xiàn)程也會(huì)被釋放
                System.out.println("創(chuàng)建了線(xiàn)程"+t);
                return t;
            }
        });
        //提交五個(gè)任務(wù)
        for (int i = 0; i < 5; i++) {
            executorService.submit(runnable);
        }
    }
}

當(dāng)線(xiàn)程提交超過(guò)五個(gè)任務(wù)時(shí),線(xiàn)程池會(huì)默認(rèn)拋出異常

監(jiān)控線(xiàn)程池

ThreadPoolExcutor提供了一組方法用于監(jiān)控線(xiàn)程池

int getActiveCount()//獲得線(xiàn)程池只當(dāng)前的獲得線(xiàn)程數(shù)量
long getCompletedTaskCount()//返回線(xiàn)程池完成任務(wù)數(shù)量
int getCorePoolSize()//線(xiàn)程池中核心任務(wù)數(shù)量
int getLargestPoolSize() //返回線(xiàn)程池中曾經(jīng)達(dá)到線(xiàn)程的最大數(shù)
int getMaximumPoolSize()//返回線(xiàn)程池的最大容量
int getPoolSize()//返回線(xiàn)程大小
BlockingQueue<Runnable> getQueue()//返回阻塞隊(duì)列
long getTaskCount()//返回線(xiàn)程池收到任務(wù)總數(shù)
public class Text {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getId() + "線(xiàn)程開(kāi)始執(zhí)行--" + System.currentTimeMillis());
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //創(chuàng)建線(xiàn)程池 使用默認(rèn)線(xiàn)程工廠(chǎng) 有界隊(duì)列  采用DiscardPolicy策略
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 5, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());
        //提交五個(gè)任務(wù)
        for (int i = 0; i < 30; i++) {
            executorService.submit(runnable);
            System.out.println("當(dāng)前線(xiàn)程核心線(xiàn)程數(shù)"+executorService.getCorePoolSize()+",最大線(xiàn)程數(shù):"+executorService.getMaximumPoolSize()+",當(dāng)前線(xiàn)程池大小:"+executorService.getPoolSize()+"活動(dòng)線(xiàn)程數(shù):"+executorService.getActiveCount()+",收到任務(wù):"+executorService.getTaskCount()+"完成任務(wù)數(shù):"+executorService.getCompletedTaskCount()+"等待任務(wù)數(shù):"+executorService.getQueue().size());
            TimeUnit.MILLISECONDS.sleep(500);
        }
        System.out.println("-------------------");
        while (executorService.getActiveCount()>=0)//繼續(xù)對(duì)線(xiàn)程池進(jìn)行檢測(cè)
        {
          System.out.println("當(dāng)前線(xiàn)程核心線(xiàn)程數(shù)"+executorService.getCorePoolSize()+",最大線(xiàn)程數(shù):"+executorService.getMaximumPoolSize()+",當(dāng)前線(xiàn)程池大?。?+executorService.getPoolSize()+"活動(dòng)線(xiàn)程數(shù):"+executorService.getActiveCount()+",收到任務(wù):"+executorService.getTaskCount()+"完成任務(wù)數(shù):"+executorService.getCompletedTaskCount()+"等待任務(wù)數(shù):"+executorService.getQueue().size());
            Thread.sleep(1000);//每1秒檢測(cè)一次
        }

    }
}

當(dāng)線(xiàn)程池大小達(dá)到了核心線(xiàn)程數(shù),線(xiàn)程會(huì)被放在等待隊(duì)列。當(dāng)線(xiàn)程池等待隊(duì)列已滿(mǎn)會(huì)開(kāi)啟新的線(xiàn)程。當(dāng)當(dāng)前線(xiàn)程大小達(dá)到最大線(xiàn)程數(shù),等待隊(duì)列也滿(mǎn)了,再提交的話(huà)會(huì)執(zhí)行DiscardPolicy策略,直接丟棄這個(gè)無(wú)法處理的任務(wù),最后30個(gè)任務(wù)只剩下15個(gè)了。

原理如圖:

擴(kuò)展線(xiàn)程池

有時(shí)候需要對(duì)線(xiàn)程池進(jìn)行擴(kuò)展,如在監(jiān)控每個(gè)任務(wù)開(kāi)始和結(jié)束時(shí)間,或者自定義其他增強(qiáng)功能。

ThreadPoolExecutor線(xiàn)程池提供了兩個(gè)方法:

protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }

線(xiàn)程池執(zhí)行某個(gè)任務(wù)前會(huì)執(zhí)行beforeExecute()方法,執(zhí)行后會(huì)調(diào)用afterExecute()方法

查看ThreadPoolExecutor源碼,在該類(lèi)中定義了一個(gè)內(nèi)部類(lèi)Worker,ThreadPoolExecutor線(xiàn)程池的工作線(xiàn)程就是Worker類(lèi)的實(shí)例,Worker實(shí)例在執(zhí)行時(shí)會(huì)調(diào)用beforeExecute與afterExecute方法。

public void run() {
            runWorker(this);
}
final void runWorker(Worker w) {
                try {
                    beforeExecute(wt, task);
                    try {
                        task.run();
                        afterExecute(task, null);
                    } catch (Throwable ex) {
                        afterExecute(task, ex);
                        throw ex;
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
    }      

部分代碼已省略,線(xiàn)程執(zhí)行前會(huì)調(diào)用beforeExecute,執(zhí)行后會(huì)調(diào)用afterExecute方法。

擴(kuò)展線(xiàn)程池示例

package com;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Text07 {
    public static void main(String[] args) {

        //定義擴(kuò)展線(xiàn)程池 定義線(xiàn)程池類(lèi)繼承ThreadPoolExecutor,然后重寫(xiě)其他方法
        ExecutorService threadPoolExecutor=
 new ThreadPoolExecutor(5,5,0, TimeUnit.SECONDS,new LinkedBlockingDeque<>()){
     //在內(nèi)部類(lèi)重寫(xiě)開(kāi)始方法
     @Override
     protected void beforeExecute(Thread t, Runnable r) {
         System.out.println(t.getId()+"線(xiàn)程準(zhǔn)備執(zhí)行任務(wù)"+((Mytask)r).name);
     }
     //在內(nèi)部類(lèi)重寫(xiě)結(jié)束方法
     @Override
     protected void afterExecute(Runnable r, Throwable t) {
         System.out.println(((Mytask)r).name+"執(zhí)行完成");
     }
     //線(xiàn)程池退出
     @Override
     protected void terminated() {
         System.out.println("線(xiàn)程池退出");
     }
 };
        for (int i = 0; i < 5; i++) {
            Mytask mytask=new Mytask("Thread"+i);
            threadPoolExecutor.execute(mytask);
        }
    }
    private  static  class  Mytask implements Runnable
    {
        private  String name;

        public  Mytask(String name)
        {
            this.name=name;
        }
        @Override
        public void run() {
            System.out.println(name+"正在被執(zhí)行"+Thread.currentThread().getId());
            try {
                Thread.sleep(1000);//模擬任務(wù)時(shí)長(zhǎng)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

優(yōu)化線(xiàn)程池大小

線(xiàn)程池大小對(duì)系統(tǒng)性能有一定影響,過(guò)大或者過(guò)小都無(wú)法方法發(fā)揮系統(tǒng)最佳性能,不需要非常精確,只要避免極大或者極小就可以了,一般來(lái)說(shuō)線(xiàn)程池大小大姚考慮CPU數(shù)量

線(xiàn)程池大小=CPU數(shù)量 * 目標(biāo)CPU使用率*(1+等待時(shí)間與計(jì)算時(shí)間的比)

線(xiàn)程池死鎖

如果線(xiàn)程池執(zhí)行中,任務(wù)A在執(zhí)行過(guò)程中提交了任務(wù)B,任務(wù)B添加到線(xiàn)程池中的等待隊(duì)列,如果A的結(jié)束需要B的執(zhí)行結(jié)果,而B(niǎo)線(xiàn)程需要等待A線(xiàn)程執(zhí)行完畢,就可能會(huì)使其他所有工作線(xiàn)程都處于等待狀態(tài),待這些任務(wù)在阻塞隊(duì)列中執(zhí)行。線(xiàn)程池中沒(méi)有可以對(duì)阻塞隊(duì)列進(jìn)行處理的線(xiàn)程,就會(huì)一直等待下去照成死鎖。

適合給線(xiàn)程池提交相互獨(dú)立的任務(wù),而不是彼此依賴(lài)的任務(wù),對(duì)于彼此依賴(lài)的任務(wù),可以考慮分別提交給不同的線(xiàn)程池來(lái)處理。

線(xiàn)程池異常信息捕獲

import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Text09 {
    public static void main(String[] args) {
        //創(chuàng)建線(xiàn)程池
        ExecutorService executorService=new ThreadPoolExecutor(5,5,0, TimeUnit.SECONDS,new SynchronousQueue<>());
        //向線(xiàn)程池中添加兩個(gè)數(shù)相處計(jì)算的任務(wù)
        for (int i = 0; i <5 ; i++) {
            executorService.submit(new Text(10,i));
        }

    }
    private  static class  Text implements  Runnable
    {
        private  int x;
        private  int y;
        public  Text(int x,int y)
        {
            this.x=x;
            this.y=y;
        }
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"線(xiàn)程x/y結(jié)果的為"+x+"/"+y+"="+(x/y));
        }
    }
}

可以看到只有四條結(jié)果,實(shí)際向線(xiàn)程池提交了五個(gè)任務(wù),但是當(dāng)i==0時(shí),產(chǎn)生了算術(shù)異常,線(xiàn)程池把該異常吃掉了,導(dǎo)致我們對(duì)該異常一無(wú)所知

解決辦法:

1.把submit改為execute

2.對(duì)線(xiàn)程池進(jìn)行擴(kuò)展,對(duì)submit進(jìn)行包裝

package com;

import java.util.concurrent.*;

public class Text09 {
    public static void main(String[] args) {
        //創(chuàng)建線(xiàn)程池  使用自定義的線(xiàn)程池
        ExecutorService executorService=new TranceThreadPoorExcuter(5,5,0, TimeUnit.SECONDS,new SynchronousQueue<>());
        //向線(xiàn)程池中添加兩個(gè)數(shù)相處計(jì)算的任務(wù)
        for (int i = 0; i <5 ; i++) {
            executorService.submit(new Text(10,i));
        }

    }
    public  static class  Text implements  Runnable
    {
        public  int x;
        public  int y;
        public  Text(int x,int y)
        {
            this.x=x;
            this.y=y;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"線(xiàn)程x/y結(jié)果的為"+x+"/"+y+"="+(x/y));
        }
    }
    //自定義線(xiàn)程池類(lèi) 對(duì)TranceThreadPoorExcuter進(jìn)行擴(kuò)展
    private  static  class  TranceThreadPoorExcuter extends  ThreadPoolExecutor
    {

        public TranceThreadPoorExcuter(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }
        //定義一個(gè)方法用于傳入兩個(gè)參數(shù) 第一個(gè)是要接受的任務(wù) 第二個(gè)是Exception
        public  Runnable warp(Runnable r,Exception e)
        {
            return new Runnable() {
                @Override
                public void run() {

                    try {
                        r.run();
                    }
                    catch (Exception e1)
                    {
                        e.printStackTrace();
                        throw e1;
                    }
                }
            };
        }
        //重寫(xiě)submit方法
        @Override
        public Future<?> submit(Runnable task) {
            return super.submit(warp(task,new Exception("客戶(hù)跟蹤異常")));
        }
        //還可以重寫(xiě)excute方法
    }
}

此方法使用了自定義的線(xiàn)程池,重寫(xiě)線(xiàn)程池中的submit方法,在submit方法中,把要傳入的任務(wù)參數(shù)帶一個(gè)捕獲異常信息的功能就可以捕獲線(xiàn)程池異常。

到此這篇關(guān)于Java利用線(xiàn)程工廠(chǎng)監(jiān)控線(xiàn)程池的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Java 線(xiàn)程工廠(chǎng)監(jiān)控線(xiàn)程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 了解spring中的CloudNetflix Hystrix彈性客戶(hù)端

    了解spring中的CloudNetflix Hystrix彈性客戶(hù)端

    這篇文章主要介紹了了解spring中的CloudNetflix Hystrix彈性客戶(hù)端,客戶(hù)端彈性模式是在遠(yuǎn)程服務(wù)發(fā)生錯(cuò)誤或表現(xiàn)不佳時(shí)保護(hù)遠(yuǎn)程資源(另一個(gè)微服務(wù)調(diào)用或者數(shù)據(jù)庫(kù)查詢(xún))免于崩潰。,需要的朋友可以參考下
    2019-06-06
  • mybatis解決<foreach>標(biāo)簽不能超過(guò)1000的問(wèn)題

    mybatis解決<foreach>標(biāo)簽不能超過(guò)1000的問(wèn)題

    MyBatis是一個(gè)開(kāi)源的持久層框架,它可以幫助開(kāi)發(fā)者簡(jiǎn)化數(shù)據(jù)庫(kù)操作的編寫(xiě),而foreach是MyBatis中的一個(gè)重要標(biāo)簽,用于在SQL語(yǔ)句中進(jìn)行循環(huán)操作,本文主要給大家介紹了mybatis解決<foreach>標(biāo)簽不能超過(guò)1000的問(wèn)題,需要的朋友可以參考下
    2024-05-05
  • 一學(xué)即會(huì)之JDK版本快速切換方法(2024)

    一學(xué)即會(huì)之JDK版本快速切換方法(2024)

    這篇文章主要介紹了一學(xué)即會(huì)之JDK版本快速切換方法,詳細(xì)給大家講解了如何下載、安裝和配置多個(gè)JDK版本,并通過(guò)設(shè)置環(huán)境變量和編寫(xiě)批處理腳本來(lái)切換JDK版本,需要的朋友可以參考下
    2025-03-03
  • Java中classpath的基本概念和配置方法詳析

    Java中classpath的基本概念和配置方法詳析

    這篇文章主要介紹了Java中的classpath概念,包括其基本概念、設(shè)置方法以及在Java應(yīng)用中的作用,在IDE中的配置也進(jìn)行了詳細(xì)說(shuō)明,并提到了一些通用注意事項(xiàng),需要的朋友可以參考下
    2025-02-02
  • java集合中的迭代器Iterator和數(shù)組內(nèi)置方法及常見(jiàn)的報(bào)錯(cuò)解決方案

    java集合中的迭代器Iterator和數(shù)組內(nèi)置方法及常見(jiàn)的報(bào)錯(cuò)解決方案

    文章介紹了Java集合框架中迭代器(Iterator)的使用,以及數(shù)組和集合的內(nèi)置方法,重點(diǎn)解釋了在遍歷集合時(shí)刪除元素時(shí)可能出現(xiàn)的`ConcurrentModificationException`異常,并說(shuō)明了如何正確地使用迭代器來(lái)刪除集合中的元素,感興趣的朋友跟隨小編一起看看吧
    2025-02-02
  • SpringBoot實(shí)現(xiàn)接口校驗(yàn)簽名調(diào)用的項(xiàng)目實(shí)踐

    SpringBoot實(shí)現(xiàn)接口校驗(yàn)簽名調(diào)用的項(xiàng)目實(shí)踐

    在以SpringBoot開(kāi)發(fā)后臺(tái)API接口時(shí),會(huì)存在哪些接口不安全的因素呢?通常如何去解決的呢?本文主要介紹了SpringBoot實(shí)現(xiàn)接口校驗(yàn)簽名調(diào)用的項(xiàng)目實(shí)踐,感興趣的可以了解一下
    2023-09-09
  • Java中抽象類(lèi)與方法的重寫(xiě)方式

    Java中抽象類(lèi)與方法的重寫(xiě)方式

    這篇文章主要介紹了Java中抽象類(lèi)與方法的重寫(xiě)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • IDEA中解決 git pull 沖突的方法

    IDEA中解決 git pull 沖突的方法

    這篇文章主要介紹了IDEA中解決 git pull 沖突的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Maven項(xiàng)目改為spring boot項(xiàng)目的方法圖解

    Maven項(xiàng)目改為spring boot項(xiàng)目的方法圖解

    這篇文章主要介紹了Maven項(xiàng)目改為spring boot項(xiàng)目的方法圖解 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • logback?OutputStreamAppender高效日志輸出源碼解析

    logback?OutputStreamAppender高效日志輸出源碼解析

    這篇文章主要介紹了為大家logback?OutputStreamAppender日志輸出效率提升示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10

最新評(píng)論

延吉市| 绩溪县| 南充市| 三原县| 宁武县| 三都| 永年县| 平顶山市| 泰宁县| 阿克陶县| 湖北省| 许昌县| 南岸区| 麻江县| 拉萨市| 连州市| 柯坪县| 措勤县| 临潭县| 凌海市| 海门市| 松原市| 淳化县| 通城县| 虎林市| 江山市| 西宁市| 汾西县| 濮阳县| 铜山县| 林周县| 峨山| 武陟县| 平塘县| 横峰县| 博野县| 安宁市| 吴桥县| 改则县| 富平县| 永兴县|