国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

多線程之線程池的應(yīng)用

2019-11-08 02:52:12
字體:
供稿:網(wǎng)友

java1.5中提供了一個(gè)非常高效實(shí)用的多線程包:java.util.concurrent,提供了大量高級(jí)工具,可以幫助開發(fā)者編寫高效易維護(hù)、結(jié)構(gòu)清晰的Java多線程程序。

線程池

之前我們?cè)谑褂枚嗑€程都是用Thread的start()來創(chuàng)建啟動(dòng)一個(gè)線程,但是在實(shí)際開發(fā)中,如果每個(gè)請(qǐng)求到達(dá)就創(chuàng)建一個(gè)新線程,開銷是相當(dāng)大的。服務(wù)器在創(chuàng)建和銷毀線程上花費(fèi)的時(shí)間和消耗的系統(tǒng)資源都相當(dāng)大,甚至可能要比在處理實(shí)際的用請(qǐng)求的時(shí)間和資源要多的多。除了創(chuàng)建和銷毀線程的開銷之外,活動(dòng)的線程也需要消耗系統(tǒng)資源。如果在一個(gè)jvm里創(chuàng)建太多的線程,可能會(huì)使系統(tǒng)由于過度消耗內(nèi)存或“切換過度”而導(dǎo)致系統(tǒng)資源不足。這就引入了線程池概念。

線程池的原理其實(shí)就是對(duì)多線程的一個(gè)管理,為了實(shí)現(xiàn)異步機(jī)制的一種方法,其實(shí)就是多個(gè)線程執(zhí)行多個(gè)任務(wù),最終這些線程通過線程池進(jìn)行管理…不用手動(dòng)去維護(hù)…一次可以處理多個(gè)任務(wù),這樣就可以迅速的進(jìn)行相應(yīng)…比如說一個(gè)網(wǎng)站成為了熱點(diǎn)網(wǎng)站,那么對(duì)于大量的點(diǎn)擊量,就必須要對(duì)每一次的點(diǎn)擊做出迅速的處理,這樣才能達(dá)到更好的交互效果…這樣就需要多個(gè)線程去處理這些請(qǐng)求,以便能夠更好的提供服務(wù)…

在java.util.concurrent包下,提供了一系列與線程池相關(guān)的類。合理的使用線程池,可以帶來多個(gè)好處:

(1)降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗;

(2)提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行;

(3)提高線程的可管理性。線程是稀缺資源,如果無限制的創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)降低系統(tǒng)的穩(wěn)定性,使用線程池可以進(jìn)行統(tǒng)一的分配,調(diào)優(yōu)和監(jiān)控。

線程池可以應(yīng)對(duì)突然大爆發(fā)量的訪問,通過有限個(gè)固定線程為大量的操作服務(wù),減少創(chuàng)建和銷毀線程所需的時(shí)間。

使用線程池:

1.創(chuàng)建線程池

2.創(chuàng)建任務(wù)

3.執(zhí)行任務(wù)

4.關(guān)閉線程池

一、創(chuàng)建線程池的方法

我們一般通過工具類Executors的靜態(tài)方法來獲取線程池或靜態(tài)方法。介紹四種常用創(chuàng)建方法

 ExecutorService executorService1 = Executors.newSingleThreadExecutor();

單例線程,表示在任意的時(shí)間段內(nèi),線程池中只有一個(gè)線程在工作…

 ExecutorService executorService2 = Executors.newFixedThreadPool(10);緩存線程池,先查看線程池中是否有當(dāng)前執(zhí)行線程的緩存,如果有就resue(復(fù)用),如果沒有,那么需要?jiǎng)?chuàng)建一個(gè)線程來完成當(dāng)前的調(diào)用.并且這類線程池只能完成一些生存期很短的一些任務(wù).并且這類線程池內(nèi)部規(guī)定能resue(復(fù)用)的線程,空閑的時(shí)間不能超過60s,一旦超過了60s,就會(huì)被移出線程池.

ExecutorService executorService3 = Executors.newScheduledThreadPool(10);固定型線程池,和newCacheThreadPool()差不多,也能夠?qū)崿F(xiàn)resue(復(fù)用),但是這個(gè)池子規(guī)定了線程的最大數(shù)量,也就是說當(dāng)池子有空閑時(shí),那么新的任務(wù)將會(huì)在空閑線程中被執(zhí)行,一旦線程池內(nèi)的線程都在進(jìn)行工作,那么新的任務(wù)就必須等待線程池有空閑的時(shí)候才能夠進(jìn)入線程池,其他的任務(wù)繼續(xù)排隊(duì)等待.這類池子沒有規(guī)定其空閑的時(shí)間到底有多長(zhǎng).這一類的池子更適用于服務(wù)器.

ExecutorService executorService4 = Executors.newCacheThreadPool();

調(diào)度型線程池,調(diào)度型線程池會(huì)根據(jù)Scheduled(任務(wù)列表)進(jìn)行延遲執(zhí)行,或者是進(jìn)行周期性的執(zhí)行.適用于一些周期性的工作.

先看一個(gè)簡(jiǎn)單例子:

    publicclass Executor {    publicstatic void main(String[] args) {        //定義了線程池中最大存在的線程數(shù)目        ExecutorService executorService=Executors.newFixedThreadPool(10);        //添加了一個(gè)任務(wù)...        executorService.execute(newRunnable() {             @Override            publicvoid run() {                while(true){                    System.out.PRintln("begincode");                    try{                        Thread.sleep(1000);                    }catch(InterruptedException e) {                        e.printStackTrace();                    }                }            }        });    }}執(zhí)行結(jié)果就是無限循環(huán)每隔1秒打印一個(gè)begincode…

二、創(chuàng)建任務(wù)

任務(wù)分為兩種一種是有返回值的,一種是沒有返回值的無返回值的任務(wù)就是一個(gè)實(shí)現(xiàn)了runnable接口的類.使用run方法有返回值的任務(wù)是一個(gè)實(shí)現(xiàn)了callable接口的類.使用call方法例子:
publicclassBegincode implementsRunnable {        publicvoidrun() {          System.out.println(“Begincode--runable”);     } }
publicclassBegincode implementscallable{       publicvoidcall() {          System.out.println(“Begincode--callable”);     } }三、執(zhí)行任務(wù)通過java.util.concurrent.ExecutorService接口對(duì)象來執(zhí)行任務(wù),該對(duì)象有兩個(gè)方法可以執(zhí)行任務(wù)execute和submit

execute這種方式提交沒有返回值,也就不能判斷是否執(zhí)行成功。

submit這種方式它會(huì)返回一個(gè)Future對(duì)象,通過future的get方法來獲取返回值,get方法會(huì)阻塞住直到任務(wù)完成。

四、關(guān)閉線程池

當(dāng)我們不需要使用線程池的時(shí)候,我們需要對(duì)其進(jìn)行關(guān)閉…有兩種方法可以關(guān)閉掉線程池…

shutdown()

shutdown并不是直接關(guān)閉線程池,而是不再接受新的任務(wù)…如果線程池內(nèi)有任務(wù),那么把這些任務(wù)執(zhí)行完畢后,關(guān)閉線程池….

shutdownNow()

這個(gè)方法表示不再接受新的任務(wù),并把任務(wù)隊(duì)列中的任務(wù)直接移出掉,如果有正在執(zhí)行的,嘗試進(jìn)行停止…

案例分享

需求:從數(shù)據(jù)庫中獲取url,并利用httpclient循環(huán)訪問url地址,并對(duì)返回結(jié)果進(jìn)行操作

分析:由于是循環(huán)的對(duì)多個(gè)url進(jìn)行訪問并獲取數(shù)據(jù),為了執(zhí)行的效率,考慮使用多線程,url數(shù)量未知如果每個(gè)任務(wù)都創(chuàng)建一個(gè)線程將消耗大量的系統(tǒng)資源,最后決定使用線程池。

給大家貼上代碼

publicclass GetMonitorDataService {     privateLogger logger = LoggerFactory.getLogger(GetMonitorDataService.class);    @Resource    privateMonitorProjectUrlMapper groupUrlMapper;    @Resource    privateMonitorDetailBatchInsertMapper monitorDetailBatchInsertMapper;    publicvoid sendData(){        //調(diào)用dao查詢所有url        MonitorProjectUrlExample example=newMonitorProjectUrlExample();        List<MonitorProjectUrl> list=groupUrlMapper.selectByExample(example);        logger.info("此次查詢數(shù)據(jù)庫中監(jiān)控url個(gè)數(shù)為"+list.size());         //獲取系統(tǒng)處理器個(gè)數(shù),作為線程池?cái)?shù)量        intnThreads=Runtime.getRuntime().availableProcessors();         //定義一個(gè)裝載多線程返回值的集合        List<MonitorDetail> result= Collections.synchronizedList(newArrayList<MonitorDetail>());        //創(chuàng)建線程池,這里定義了一個(gè)創(chuàng)建線程池的工具類,避免了創(chuàng)建多個(gè)線程池        ExecutorService executorService = ThreadPoolFactoryUtil.getExecutorService(nThreads);        //遍歷數(shù)據(jù)庫取出的url        if(list!=null&&list.size()>0) {            for(MonitorProjectUrl monitorProjectUrl : list) {                String url = monitorProjectUrl.getMonitorUrl();                //創(chuàng)建任務(wù)                ThreadTask threadTask = newThreadTask(url, result);                //執(zhí)行任務(wù)                executorService.execute(threadTask);            }            //對(duì)數(shù)據(jù)進(jìn)行操作            saveData(result);        }    }任務(wù):

publicclass ThreadTask implementsRunnable{    //這里實(shí)現(xiàn)runnable接口    privateString url;    privateList<MonitorDetail> list;    publicThreadTask(String url,List<MonitorDetail> list){        this.url=url;        this.list=list;    }    //把獲取的數(shù)據(jù)進(jìn)行處理    @Override    publicvoid run() {        MonitorDetail detail = HttpClientUtil.send(url, MonitorDetail.class);        list.add(detail);    } }以上是本人的一些分享,希望和大家多多交流。如果哪里有不足,希望大家指出!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 绩溪县| 东乡族自治县| 凤山市| 安平县| 敦化市| 松潘县| 叶城县| 南华县| 建德市| 启东市| 黑河市| 开江县| 隆林| 武安市| 望城县| 木里| 惠水县| 双柏县| 巴南区| 长垣县| 福建省| 贵定县| 嘉定区| 宜丰县| 伊金霍洛旗| 赤壁市| 株洲市| 唐山市| 德安县| 邹平县| 股票| 彰武县| 宜州市| 阿巴嘎旗| 许昌市| 苍溪县| 沙坪坝区| 天门市| 正镶白旗| 九龙县| 浦城县|