国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

模擬病毒掃描程序(Executors、ScheduledExecutorService類)

antz / 2578人閱讀

摘要:類重點(diǎn)是那個(gè)病毒掃描程序的例子,認(rèn)真看三遍。會從線程池中選擇線程,并將對象提交給線程任務(wù)。比如病毒掃描,你可以使用類實(shí)現(xiàn)的執(zhí)行器服務(wù),每小時(shí)運(yùn)行一次病毒掃描。該應(yīng)用是以固定頻率執(zhí)行的病毒掃描程序。

Executors類

重點(diǎn)是那個(gè)病毒掃描程序的例子,認(rèn)真看三遍。本文花了四個(gè)小時(shí)。

GitHub代碼歡迎star。

小白認(rèn)為學(xué)習(xí)語言最好的方式就是模仿思考別人為什么這么寫。結(jié)合栗子效果更好,也能記住知識點(diǎn)

Executors類允許創(chuàng)建線程池并返回ExecutorService對象,執(zhí)行器提供了將任務(wù)提交與對任務(wù)進(jìn)行解耦的標(biāo)準(zhǔn)方法,除了對基本的線程生命周期提供支持外,窒息功能其還提供統(tǒng)計(jì)收集,應(yīng)用管理及監(jiān)控方面的功能。這一切都基于 生產(chǎn)者-消費(fèi)者模式。 使用這種設(shè)計(jì)模式可以對大型并發(fā)應(yīng)用程序很好的進(jìn)行擴(kuò)展。

使用這種服務(wù)對象,可以運(yùn)行Runnable和Callable類的實(shí)力,你只需要做的是提交任務(wù)給服務(wù)對象就可以。ExecutorService會從線程池中選擇線程,并將Runnable對象提交給線程任務(wù)。當(dāng)任務(wù)結(jié)束時(shí),線程并不會銷毀 ,而是返回到線程池中繼續(xù)執(zhí)行后續(xù)的其他任務(wù),這樣可以 避免創(chuàng)建和銷毀線程帶來的額外開銷

Executors類有許多靜態(tài)方法可用來創(chuàng)建線程池:

1、newFixedTHreadPool方法能夠創(chuàng)建固定大小的線程池。線程池中的線程將被用來處理任務(wù)請求,如果線程處于空閑狀態(tài),線程不會銷毀,而是會被存放線程池中一段不確定的是將

2、newCachedThreadPool,使用該方法創(chuàng)建的線程池中的線程會在空閑60秒之后自動銷毀,

3、newSingleThreadExecutor該方法僅創(chuàng)建一個(gè)線程,當(dāng)任務(wù)結(jié)束后不會銷毀而是用于處理其他任務(wù)。對于多個(gè)任務(wù)同時(shí)請求,則使用隊(duì)列來維護(hù)所有待處理的請求。隨后會順序執(zhí)行。

4、newScheduledThreadPool可以把它看作是java.util.Timer的替代品,該方法創(chuàng)建固定大小的線程池用來調(diào)度執(zhí)行任務(wù),并返回一個(gè)ScheduledExecutorService對象,該對象提供了若干個(gè)方法用于執(zhí)行任務(wù)的調(diào)度執(zhí)行。

創(chuàng)建線程池以進(jìn)行任務(wù)調(diào)度

有時(shí)創(chuàng)建可在一定時(shí)間延遲后執(zhí)行的線程,可以設(shè)置一個(gè)報(bào)警器在一段時(shí)間過后報(bào)警。在某些情況下,你也希望以 一定的頻率或固定時(shí)間間隔反復(fù)執(zhí)行線程。
比如病毒掃描,你可以使用newScheduledThreadPool類實(shí)現(xiàn)的執(zhí)行器服務(wù),每24小時(shí)運(yùn)行一次病毒掃描。如果有多個(gè)磁盤或大容量的磁盤需要掃描,將掃描的任務(wù)分解為多個(gè)單元。讓每個(gè)單元掃描某個(gè)特定的磁盤。

另一凸顯此服務(wù)很實(shí)用的應(yīng)用場景是新聞聚合器。聚合器從多個(gè)新聞源收集最新新聞,并將它們排列在客戶端以供閱讀,多個(gè)數(shù)據(jù)源獲取可以并發(fā)執(zhí)行,而這根據(jù)目標(biāo)數(shù)據(jù)源的網(wǎng)絡(luò)狀況,花費(fèi)的時(shí)間會不一樣。客戶端和數(shù)據(jù)源的同步會周期性地執(zhí)行。如果這樣的同步操作頻率很高,新的同步操作和當(dāng)前正在執(zhí)行的操作就有可能出現(xiàn)重疊。在這種情況下,最好給每次任務(wù)的執(zhí)行設(shè)固定的時(shí)間間隔,ScheduledExecutosService可以幫你實(shí)現(xiàn)這樣的需求。

ScheduledExecutorService類

1、ScheduledExecutorService 類提供了名為schedule的方法用于設(shè)定任務(wù)的未來執(zhí)行。schedule方法有兩個(gè)重載版本:

//Creates and executes a ScheduledFuture that becomes enabled after the given delay.
 ScheduledFuture     schedule(Callable callable, long delay, TimeUnit unit)
//Creates and executes a one-shot action that becomes enabled after the given delay.
ScheduledFuture     schedule(Runnable command, long delay, TimeUnit unit)

schedule方法接收三個(gè)參數(shù):Callable和Runnable接口、延遲時(shí)間以及時(shí)間單位。該方法安排由 Callable和Runnable指定的任務(wù)在給定的延遲時(shí)間后執(zhí)行。時(shí)間單位 由該方法的第三個(gè)參數(shù)指定。方法會返回一個(gè)Future對象給調(diào)用方。

2、除了這個(gè)簡單的延遲執(zhí)行之外,ScheduledExecutorService類還提供了scheduleAtFixedRate方法,該任務(wù)可以指定任務(wù)按照一定的頻率執(zhí)行。

//Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period;
//that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.
ScheduledFuture     scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

第一次執(zhí)行發(fā)生在給定的延遲之后,后續(xù)執(zhí)行發(fā)生在“延遲+固定時(shí)間”,“延遲+2*固定周期”,依次類推,這種方法可以用于病毒掃描

3、scheduleWithFiedDelay方法在給定延遲之后第一次執(zhí)行任務(wù)。之后按照固定好的時(shí)間間隔執(zhí)行,時(shí)間間隔遞歸你以為本次任務(wù)運(yùn)行到下一次任務(wù)的開始。這類調(diào)度可以用于新聞聚合應(yīng)用。

//Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.
ScheduledFuture     scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
任務(wù)的調(diào)度執(zhí)行(重點(diǎn)在匿名線程)
/**
 * Created by guo on 2018/2/16.
 * 演示任務(wù)調(diào)度執(zhí)行
 * 需求:
 * 如何讓任務(wù)以一定的頻率執(zhí)行。
 * 1、該應(yīng)用是以固定頻率執(zhí)行的病毒掃描程序。
 * 2、當(dāng)掃描開始時(shí),程序彈出窗口以顯示掃描進(jìn)度,當(dāng)磁盤上所有文件被掃描之后,任務(wù)會停止。
 * 3、每次掃描都需要不同的時(shí)間,通過讓線程隨機(jī)睡眠一段時(shí)間來模擬這個(gè)過程。
 * 4、掃描結(jié)束之后,狀態(tài)窗口會被關(guān)閉,知道下次掃描才會彈出,
 */
public class VirusScanner {
    private static JFrame appFrame;
    private static JLabel statusString;
    private int scanNumber = 0;
    //1、調(diào)用Executors類的newScheduledThreadPool方法來創(chuàng)建線程池。
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    private static final GregorianCalendar calendar = new GregorianCalendar();
    private static VirusScanner app = new VirusScanner();

    /**
     * scanDisk方法執(zhí)行實(shí)際的掃描工作
     */
    public void scanDisk() {
        //2、使用線程池中的線程來解決多重并發(fā)掃描。
        final Runnable scanner = new Runnable() {
            @Override
            public void run() {
                try {
                    //將狀態(tài)窗口顯示給用戶
                    appFrame.setVisible(true);
                    scanNumber++;
                    Calendar cal = Calendar.getInstance();
                    //顯示掃描數(shù)以及掃描開始時(shí)間,接下來,讓當(dāng)前線程隨機(jī)睡一段時(shí)間。
                    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM);
                    statusString.setText(" Scan" + scanNumber + " started at" + df.format(cal.getTime()));
                    //常數(shù)1000是用來確保窗口至少顯示1秒。在實(shí)際程序中,病毒掃描代碼會放在sleep語句所在的位置。
                    //讓線程休眠是假裝病毒掃描持續(xù)一段時(shí)間,
                    //當(dāng)線程從休眠中喚醒時(shí),我們隱藏了窗口,這讓用戶感覺當(dāng)前一輪已經(jīng)結(jié)束。
                    //題外話1:請卸載國產(chǎn)360,QQ管家,小白可以無視。需要的組件可以下載綠色版。(明明是一個(gè)開源軟件,你卻說那高危險(xiǎn)。明明是https://www.github.com開頭。)
                    //題外話2:感謝 架構(gòu)@奇虎360,@江湖人稱小白哥。謝謝你的心意,能力沒到那,你還不能成為我職業(yè)生涯的第一位貴人。騷年,加油吧,越努力,越幸運(yùn)。
                    Thread.sleep(1000 + new Random().nextInt(10000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //重點(diǎn):3、使用之前創(chuàng)建的調(diào)度器來讓掃描程序以固定頻率執(zhí)行。
        //         a、掃描任務(wù)在最初的一秒延遲之后會以每隔15秒的頻率運(yùn)行
        //         b、調(diào)用器會返回一個(gè)Future對象,用于之后取消掃描任務(wù)。
        //         c、為了能夠進(jìn)行取消操作,創(chuàng)建另一個(gè)匿名線程。
        //         d、以下代碼所有時(shí)間單位為秒,目前只是模擬的效果。
        //         e、在實(shí)際應(yīng)用中,病毒掃描應(yīng)當(dāng)每天或每幾小時(shí)執(zhí)行一次
        final ScheduledFuture scanManager = scheduler.scheduleAtFixedRate(scanner, 1, 15, TimeUnit.SECONDS);
        /**
         * 匿名線程
         * 這個(gè)線程只在60秒延遲之后運(yùn)行一次,模擬會以一分鐘的總時(shí)間周期執(zhí)行
         * 每隔15秒,病毒掃描狀態(tài)窗口會彈出,并且顯示請留1秒,或更長時(shí)間。
         */
        scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                //4、取消病毒掃描任務(wù),并關(guān)閉調(diào)度器和狀態(tài)窗口
                scanManager.cancel(true);
                scheduler.shutdown();
                appFrame.dispose();

            }
        }, 60, TimeUnit.SECONDS);
    }


}
主函數(shù)(不是重點(diǎn))
/**
 * 不是重點(diǎn)的main方法:
 * 創(chuàng)建狀態(tài)窗口、設(shè)置并調(diào)用scanDisk方法。
 * 注意:主線程會在之后立刻結(jié)束,而在scanDisk方法中創(chuàng)建的線程會在接下來一分鐘內(nèi)繼續(xù)運(yùn)行。
 */
public static void main(String[] args) {
    appFrame = new JFrame();
    Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
    appFrame.setSize(400, 70);
    appFrame.setLocation(dimension.width / 2 - appFrame.getWidth() / 2,
            dimension.height / 2 - appFrame.getHeight() / 2);
    statusString = new JLabel();
    appFrame.add(statusString);
    appFrame.setVisible(false);
    app.scanDisk();

}
獲取首個(gè)已結(jié)束的運(yùn)行結(jié)果

之前已經(jīng)學(xué)了如何將任務(wù)提交給執(zhí)行器立即執(zhí)行、延遲以及周期性的運(yùn)行 (計(jì)算年銷售額) 還了解到執(zhí)行器可以提供并維護(hù)多個(gè)線程并發(fā)的執(zhí)行任務(wù) (模擬可取消任務(wù)的股票交易處理程序) 。在某些情況下,當(dāng)提交多個(gè)任務(wù)給執(zhí)行器,你可能希望處理任意以結(jié)束任務(wù)的結(jié)果,而不像等到每個(gè)任務(wù)都執(zhí)行結(jié)束。目前只用過執(zhí)行器的get方法會等待任務(wù)結(jié)束。當(dāng)任務(wù)提交時(shí),可以創(chuàng)建循環(huán)來獲取每個(gè)計(jì)算結(jié)果,代碼如下:

for(Future result : results) {
  result.get();
}

這樣就可以順序的獲取結(jié)果,但如果某個(gè)特定的任務(wù)需要長時(shí)間才能結(jié)束,那么當(dāng)前的get調(diào)用會一直阻塞.在這種情況下,即使其他任務(wù)已經(jīng)提前完成,也無法獲取結(jié)果,為了解決這個(gè)問題,可以使用ExecutorCompletionService類,該類會檢測提交給執(zhí)行器的任務(wù),通過take方法,可以一個(gè)個(gè)地獲取到任務(wù)執(zhí)行的結(jié)果。

待續(xù)...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/68491.html

相關(guān)文章

  • java高并發(fā)系列 - 第19天:JUC中的Executor框架詳解1,全面掌握java并發(fā)相關(guān)技術(shù)

    摘要:有三種狀態(tài)運(yùn)行關(guān)閉終止。類類,提供了一系列工廠方法用于創(chuàng)建線程池,返回的線程池都實(shí)現(xiàn)了接口。線程池的大小一旦達(dá)到最大值就會保持不變,在提交新任務(wù),任務(wù)將會進(jìn)入等待隊(duì)列中等待。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。 這是java高并發(fā)系列第19篇文章。 本文主要內(nèi)容 介紹Executor框架相關(guān)內(nèi)容 介紹Executor 介紹ExecutorService 介紹線程池ThreadP...

    icattlecoder 評論0 收藏0
  • Java 8 并發(fā)教程:線程和執(zhí)行器

    摘要:在這個(gè)示例中我們使用了一個(gè)單線程線程池的。在延遲消逝后,任務(wù)將會并發(fā)執(zhí)行。這是并發(fā)系列教程的第一部分。第一部分線程和執(zhí)行器第二部分同步和鎖第三部分原子操作和 Java 8 并發(fā)教程:線程和執(zhí)行器 原文:Java 8 Concurrency Tutorial: Threads and Executors 譯者:BlankKelly 來源:Java8并發(fā)教程:Threads和Execut...

    jsdt 評論0 收藏0
  • 初讀《Java并發(fā)編程的藝術(shù)》-第十章:Executor框架 -10.1 Executor框架簡介

    摘要:線程的啟動與銷毀都與本地線程同步。操作系統(tǒng)會調(diào)度所有線程并將它們分配給可用的。框架的成員主要成員線程池接口接口接口以及工具類。創(chuàng)建單個(gè)線程的接口與其實(shí)現(xiàn)類用于表示異步計(jì)算的結(jié)果。參考書籍并發(fā)編程的藝術(shù)方騰飛魏鵬程曉明著 在java中,直接使用線程來異步的執(zhí)行任務(wù),線程的每次創(chuàng)建與銷毀需要一定的計(jì)算機(jī)資源開銷。每個(gè)任務(wù)創(chuàng)建一個(gè)線程的話,當(dāng)任務(wù)數(shù)量多的時(shí)候,則對應(yīng)的創(chuàng)建銷毀開銷會消耗大量...

    aisuhua 評論0 收藏0
  • Java ThreadPoolExecutor 線程池

    摘要:是一個(gè)中的工具類提供工廠方法來創(chuàng)建不同類型的線程池從上圖中也可以看出的創(chuàng)建線程池的方法創(chuàng)建出來的線程池都實(shí)現(xiàn)了接口常用方法有以下幾個(gè)創(chuàng)建固定數(shù)目線程的線程池超出的線程會在隊(duì)列中等待創(chuàng)建一個(gè)可緩存線程池如果線程池長度超過處理需要可靈活回收空閑 Executors Executors 是一個(gè)Java中的工具類. 提供工廠方法來創(chuàng)建不同類型的線程池. showImg(https://segm...

    CollinPeng 評論0 收藏0
  • Java 8 并發(fā): Threads 和 Executors

    摘要:能夠異步的執(zhí)行任務(wù),并且通常管理一個(gè)線程池。這樣我們就不用手動的去創(chuàng)建線程了,線程池中的所有線程都將被重用。在之后不能再提交任務(wù)到線程池。它不使用固定大小的線程池,默認(rèn)情況下是主機(jī)的可用內(nèi)核數(shù)。 原文地址: Java 8 Concurrency Tutorial: Threads and Executors Java 5 初次引入了Concurrency API,并在隨后的發(fā)布版本中...

    J4ck_Chan 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<