一名示威者還爬到銅牛背上,搖著一面綠色旗幟

一名示威者還爬到銅牛背上,搖著一面綠色旗幟。不過,數名抗議人士稍後便動手清理潑灑在地面上的道具鮮血。「反抗滅絕」華爾街示威行動籌畫者Justin Becker接受訪問時說,石油企業與華爾街金融機構關係密切:「這裡沾染了這個世界的鮮血。」

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※幫你考照過關,堆高機裝卸操作教學影片大公開 !

※高效率洗滌塔活性碳設備,能去除多少有機溶劑?

※飲用桶裝水到底安不安全? 破解錯誤迷思!

※十大封口機人氣排行榜-烘焙必備幫手!

※票選推薦煮婦最愛手壓封口機,省荷包不犧牲品質

※各種升降平台款式?

聯合利華承諾:2025年前減半塑膠用量

英荷消費品生產商聯合利華(Unilever)今天表示,2025年前將減半旗下產品使用的新塑膠量,從目前1年使用70萬公噸塑膠,減半到低於35萬公噸。

聯合利華將減少35萬公噸「原生塑膠」用量,其中10萬公噸來自直接減少塑膠包裝,例如製造可重複利用的包裝或可補充包裝、採用替代包裝,或是完全不會用到塑膠的「裸賣」方式。

另25公噸減量目標則會從使用回收塑膠下手。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※示波器探測執行效能最佳化的8大秘訣

※專業客製化禮物、贈品設計,辦公用品常見【L夾】搖身一變大受好評!!

※全自動飲水機與一般飲水機差異在哪?

※橡膠加工製品可用在哪些用途?

※如何知道自已的電腦cpu支不支持AVX指令集?

※票選推薦煮婦最愛手壓封口機,省荷包不犧牲品質

全球氣候抗爭大串聯 華爾街銅牛濺血

響應環保組織「反抗滅絕」氣候抗爭全球大串聯活動的示威人士,7日在世界各地主要城市紛紛上街抗議,要求各國政府要針對氣候變遷採取更為迫切的因應之道。紐約知名景點華爾街銅牛也遭到波及,被抗議人士灑上道具鮮血。

一名示威者還爬到銅牛背上,搖著一面綠色旗幟。不過,數名抗議人士稍後便動手清理潑灑在地面上的道具鮮血。「反抗滅絕」華爾街示威行動籌畫者Justin Becker接受訪問時說,石油企業與華爾街金融機構關係密切:「這裡沾染了這個世界的鮮血。」

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※各大品牌中古空壓機情報站

※選用哪種桶裝水,外宿露營超方便?

※連續封口機購物網-不怕你比價,就怕你買貴!

※塑膠射出成型不良品原因及改善對策 !

※高價位跟低價位的示波器又有何差異?

※找尋中部室外倉儲、保稅倉庫、運輸物流一條龍服務

台中市政府8日在龍井區召開行動市政會議,盧秀燕會中表示

台中市政府8日在龍井區召開行動市政會議,盧秀燕會中表示,龍井區就是台中火力發電廠的所在地,加上近日因境外污染移入導致空氣品質不佳,雖然境外移入不是地方城市可以單獨處理,不過面對空污,市府一定持續加強取締境內空污,改善在地污染。

盧秀燕說,龍井是中火所在地,這些經費是居民「用命搏來的」,她向大家保證,市府絕對會補到位,不讓居民的權益受到損害。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※噴霧洗滌塔實際應用案例分享

※示波器鮮為人知的使用技巧?

※客製專屬滑鼠墊、可愛造型L夾、L型資料夾、透明證件套、手提袋,專業印刷設計廠商!  

※使用真空封口機常見問題?

※高價位跟低價位的示波器又有何差異?

※特殊造型滑鼠墊去哪買?

聯合利華將減少35萬公噸「原生塑膠」用量

聯合利華將減少35萬公噸「原生塑膠」用量,其中10萬公噸來自直接減少塑膠包裝,例如製造可重複利用的包裝或可補充包裝、採用替代包裝,或是完全不會用到塑膠的「裸賣」方式。

另25公噸減量目標則會從使用回收塑膠下手。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※飲水機設備有哪些?

※如何選購橡膠製品規格有哪些?

※AVX Distributor、AVX TPS及 AVX鉭質電容器 規格有哪些?各別作用在於?

※nbr乳膠手套可適用在什麼環境?

※空壓機何時可換油? 教你正確觀念與維護 !

※真空封口機該不該買?使用心得分享

皮博的研究顯示,人類知道的物質如恆星、行星和人類自己

皮博的研究顯示,人類知道的物質如恆星、行星和人類自己,只佔宇宙5%,其餘95%都是由「未知的暗物質和暗能量」構成。

梅爾和奎洛茲1995年發現系外行星「飛馬座51b」,與木星大小類似,諾貝爾委員會說,這兩名科學家「帶動天文學的革命」,從那時候開始,科學家在銀河系發現四千多顆系外行星,「如今仍在這個奇異新世界持續探索,發現各色各樣的系外行星,在大小、形態和軌道方面都不同」。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※堆高機基本駕駛指導教學(影片)

※廢氣洗滌塔,叫得動, 找得到的專業廠商‎

※市面十大品牌封口機!該如何選購?

※塑膠射出成型加工商品有哪些?

※選用哪種桶裝水,外宿露營超方便?

※各款電動堆高機價格?

關渡自然保留區 北市府擬全面解編 專家︰捨歷史地位及價值

台北市的關渡自然保留區,紅樹林生長茂密,影響防洪效果、水鳥棲息,為了改善陸域化情形,北市府去年拋出部分解編的構想,引發各界撻伐,不料如今政策卻是打算將整個自然保留區全數解編,原不准民眾進出限制也大解禁,最快今年提送農委會定奪。

值得一提的是,關渡自然保留區現有8公頃私地,政府無法徵收,私地主也不能處分產權,一度向民代陳情;台北市動保處表示,若確定解編後,該區域改適用「濕地保育法」,附有徵收條款,未來內政部有特殊利用或保育需求,就可徵收私地。

動保處表示,北市府原本僅考慮解編20%,但考量紅樹林擴張快速,若疏伐範圍不大,紅樹林很快就長回來,等於「治標不治本」,才決定改為100 %解編,未來仍透過「濕地保育法」管制。

台北市野鳥學會總幹事陳仕泓直言,大家都同意處理紅樹林蔓延問題,所以鳥會一開始表達部分解編,不料過了整整一年,北市府突然拋出100%解編方案,此舉根本廢止自然保留區,也創下全國首例,令人感到錯愕。

陳仕泓以古蹟龍山寺為例,難道古蹟維護不好,就廢止古蹟資格?北市府的邏輯令人不解,修訂「文資法」才是解決之道,不是乾脆廢止自然保留區。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※使用真空封口機常見問題?

※高價位跟低價位的示波器又有何差異?

※各大百貨每波促銷贈品活動,限量知名LOGOL型資料夾,獨家販售中!!

※哪裡有合版印刷優惠,尋找L夾客製化印刷廠商?

※如何正確使用飲水機?

※洗滌塔運作原理介紹

中火減煤砍補償 盧秀燕承諾市府補足

近期台灣西半部空氣品質不良,台中市長盧秀燕8日指出,市府針對空污污染源將直接開罰、強力取締,至於台中火力發電廠減煤、降載,台電將減少促協金,市府將補足基礎建設預算。

台中市政府8日在龍井區召開行動市政會議,盧秀燕會中表示,龍井區就是台中火力發電廠的所在地,加上近日因境外污染移入導致空氣品質不佳,雖然境外移入不是地方城市可以單獨處理,不過面對空污,市府一定持續加強取締境內空污,改善在地污染。

盧秀燕說,龍井是中火所在地,這些經費是居民「用命搏來的」,她向大家保證,市府絕對會補到位,不讓居民的權益受到損害。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※一般小吃店常見使用的nbr耐油手套,是否有含耐酸鹼作用?

※迴轉式空壓機性能介紹 !

※(全省)堆高機租賃保養一覽表

※高效率洗滌塔活性碳設備,能去除多少有機溶劑?

※塑膠射出成型技師工作甘苦談

※專業銷售、服務第一,桶裝水推薦品牌?

xeus-clickhouse: Jupyter 的 ClickHouse 內核

在科學計算領域,Jupyter 是一個使用非常廣泛的集成開發環境,它支持多種主流的編程語言比如 Python, C++, R 或者 Julia。同時,數據科學最重要的還是數據,而 SQL 是操作數據最直觀的語言。前段時間看到一篇文章[1],有人給 sqlite 做了一個 jupyter 的內核,感覺很有意思。所以我嘗試給 ClickHouse 做了一個 jupyter 的內核,目前已經有了一個可以試用的版本,下面做一個簡單介紹。

clickhouse

現狀

新內核允許用戶用 ClickHouse SQL 的語法直接操作遠程 CH 數據庫,通過一些擴展操作比如 %CONNECT 支持與 ch cli 一樣的連接參數,後續也有計劃使用 jupyter magics 支持更多的數據可視化操作。

項目參考了 jupyter sqlite 內核的實現方式,是基於 xeus [2]框架來實現的。xeus 是一個 c++ 的 lib 庫,它對 jupyter 的內核做了很好的封裝,我們只需要專註於內核相關的功能就可以了。目前對於 ch 的操作基於 clickhouse-cpp 來實現,它是 ch 的 cpp 客戶端。

ch-sql

目前實現處於早期階段,但是基礎功能已經可用。它支持了幾乎 CH 所有 SQL 語法,具體例子可以參考 examples/clickhouse.ipynb [4]。xeus-clickhouse 在 jupyter notebook 和 jupyter lab 中以 HTML 表格的形式展示數據;在 jupyter console 中,我們使用 tabulate 庫只做純文本的表格。

未來

對於 xeus-clickhouse 未來的規劃是,先打磨好穩定性,目前已知的還有一個非法字符導致內核崩潰的問題,已經提交 issue 給 xeus 倉庫;另外clickhouse-cpp 不支持 ssl 連接。除了基礎功能的打磨,還計劃通過支持更多的 jupyter magic 來實現數據的可視化渲染,提供更方便的數據可視化能力。

使用

我製作了一個 Docker 鏡像發布在 docker-hub [3] ,不需要安裝任何環境就可以試用:

# start jupyter with clickhouse kernal
docker run -p 8888:8888 wangfenjin/xeus-clickhouse:v0.1.0

# start a local clickhouse for testing
docker run -d --name jupyter-clickhouse-server -p 8123:8123 --ulimit nofile=262144:262144 yandex/clickhouse-server

# open the example/clickhouse.ipynb and connect to local server by
# %CONNECT --host host.docker.internal --port 8123

在 docker 裏面連接另外一個 docker 中的 ch 可能會有問題,感覺是目前 clickhouse-cpp 對於網絡的處理不太完善。感興趣的同學也可以下載代碼自己編譯,具體的編譯流程見 github 倉庫 [4]。歡迎大家試用!

鏈接

  1. https://blog.jupyter.org/a-jupyter-kernel-for-sqlite-9549c5dcf551
  2. https://github.com/jupyter-xeus/xeus
  3. https://hub.docker.com/r/wangfenjin/xeus-clickhouse
  4. https://github.com/wangfenjin/xeus-clickhouse

  本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

併發07–線程池及Executor框架

一、JAVA中的線程池

線程池的實現原理及流程如下圖所示:

 

 

   如上圖所示,當一個線程提交到線程池時(execute()或submit()),先判斷核心線程數(corePoolSize)是否已滿,如果未滿,則直接創建線程執行任務;如果已滿,則判斷隊列(BlockingQueue)是否已滿,如果未滿,則將線程添加到隊列中;如果已滿,則判斷線程池(maximumPoolSize)是否已滿,如果未滿,則創建線程池執行任務;如果線程池已滿,則交給飽和策略(RejectedExecutionHandler.rejectExcution())來處理。

  可以看下線程池ThreadPoolExecutor的全參構造函數源碼:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

對其入參釋義如下:

參數 描述 作用
coolPoolSize 線程核心線程數 當一個任務提交到線程池時,線程池會創建一個線程來執行任務,即使其他的核心線程足夠執行新任務,也會創建線程,直到需要執行的任務數大於核心線程數后才不再創建;如果線程池先調用了preStartAllCoreThread()方法,則會先啟動所有核心線程。
maximumPoolSize 線程池最大線程數 如果隊列滿了,並且已創建的線程數小於該值,則會創建新的線程執行任務。這裏需要說明一點,如果使用的隊列時無界隊列,那麼該值無用。
keepAliveTime 存活時間 當線程池中線程超過超時時間沒有新的任務進入,則停止該線程;只會停止多於核心線程數的那幾個線程。
unit 線程存活的時間單位 可以有天、小時、分鐘、秒、毫秒、微妙、納秒
workQueue 任務隊列

用於保存等待執行任務的阻塞隊列。可以選擇如下幾個隊列:數組結構的有界隊列ArrayBlockingQueue、鏈表結果的有界隊列LinkedBlockingQueue、不存儲元素的阻塞隊列SynchronousQueue、一個具有優先級的無界阻塞隊列PriortyBlockingQueue

threadFactory 創建線程的工廠

可以通過工廠給每個線程創建更有意義的名字。使用Guava提供的ThreadFactoryBuilder可以快速的給線程池裡的線程創建有意義的名字,代碼如下

new ThreadFactoryBuilder().setNameFormat(“aaaaaaaa”).build();

handler 包和策略

當隊列和線程都滿了,說明線程池處於飽和狀態,那麼必須採取一種策略來處理新提交的任務。

AbortPolicy(默認),表示無法處理新任務時拋出異常。

CallerRunsPolicy:只有調用者所在線程來運行

DiscardOldestPolicy:丟棄隊列里最近的一個任務,並執行當前任務

DiscardPolicy:不處理,直接丟棄

  上面說到,向線程池提交任務有兩種方法,分別是execute()和submit(),兩者的區別主要是execute()提交的是不需要有返回值的任務,而submit提交的是需要有返回值的任務,並且submit()會返回一個Furure對象,並且可以使用future.get()方法獲取返回值,並且get方法會阻塞,直到有返回值。

  線程池的關閉有shutdown()和shutdownNow兩個方法,他們的原理是遍歷線程池中的工作線程,然後逐個調用interrupt方法來中斷線程,所以無法中斷的線程可能永遠無法終止;但是二者也有區別,shutdownNow是將線程池的狀態設置為STOP,然後嘗試停止所有正在執行或者暫停的線程,並返回等待執行任務列表;而shutdown只是將線程池的狀態設置成SHUTDOWN,然後中斷所有沒有正在執行的任務。當調用這兩個方法中的任何一個后,isShutdown方法就會返回true,當所有任務都已經關閉后,調用isTerminaed方法會返回true。

  使用線程池時,需要從任務的性質(IO密集型還是CPU密集型或是混合型)、任務的優先級、任務的執行時常、任務的依賴性(是否依賴其他系統資源,如數據庫連接等)來綜合判斷,比如說,CPU密集型,就可以就可以配置N+1個線程個數,其中N為CPU核數,如果是IO密集型,則可以配置2*N個線程數;如果是混合型的任務,可以將其拆分成IO密集型和CPU密集型,但是如果兩個任務的執行時間相差較大,則沒有必要進行拆分;優先級不同的任務可以使用優先級隊列PriortyBlockingQueue來處理;依賴數據出等其它資源的線程池,比如說依賴數據庫,那麼就可以加大線程數量,因為在等待sql執行的時候,線程是處於空閑狀態;另外,最好使用有界隊列,因為無界隊列,因為有界隊列可以增加系統的穩定性和預警能力。

  對於線程的監控,還有以下幾個方法可以使用:

方法 描述
taskCount() 線程池需要執行的任務數量
completedTskCount 線程池運行過程中已經執行完畢的任務數量
IarestPoolSize 線程池中曾經創建過的最大線程數
getPoolSize 線程池的線程數量
getActiveCount 獲取活動的線程數

二、Exector框架

   在java中,是用線程來異步執行任務,java線程的創建與銷毀需要一定的開銷。如果我們為每一個任務創建一個線程的話,這些線程就會消耗大量的計算資源,會使處於高負荷的應用崩潰。

  在HotSpot虛擬機中,JAVA線程被一對一的映射為本地操作系統線程。JAVA線程啟動時會創建一個本地操作系統線程,當該JAVA線程終止時,這個操作系統線程也會被收回,操作系統會調用多有線程並將他們分配給可用的CPU。

 

   Executor框架的兩級調度模型如上圖所示,應用程序通過Executor控制上層的調度,而下層的調用由操作系統內核控制,將線程映射到硬件處理器上,下層的調用不受應用程序的控制。

   關於Executor的組成部分如下所示:

元素 描述
任務 包括被執行任務需要實現的接口Runnable和Callable接口
任務的執行 包括任務執行機制的核心接口Executor,以及繼承自Executor的ExecutorService接口。Executor接口有兩個關鍵的實現類實現了ExecutorService接口:ThreadPoolExecutor和ScheduledThreadPoolExecutor
異步計算的結果 包括接口Future和實現Future接口的FurureTask類

  Executor框架使用示意圖如下:

 

 

   如上圖所示,主線程首先創建實現Runnable或Callable接口的任務對象,然後把任務對象提交給ExecutorService執行,如果使用的是submit提交,執行完畢后將返回一個實現Future接口的對象,最後,主線程可以執行FutureTask.get()方法來獲取返回值;主線程也可以調用FutureTask.cancel()方法來取消此任務的執行。

  Executor框架的成員如下:

成員 描述 子類 描述
ThreadPoolExecutor

通常使用工廠類Executors來創建,Executors可以創建三種類型的ThreadPoolExecutor

固定線程數的FixedThreadPool

適用於為了滿足資源管理的需求,而需要限制當前線程數量的應用場景,它適用於負載比較重的應用。
單一線程的SingleThreadPool 適用於需要保證順序的執行各個任務,並且在任意時間點都不會有多個線程活動的場景。
根據需要創建線程的CacheThreadPool 這是一個無界的線程池,適用於執行很多短期異步任務的小程序,或者是負載比較輕的服務器。
ScheduledThreadPoolExecutor 通常使用工廠類Executors創建,Executors可以創建兩種類型的ScheduledThreadPoolExecutor 包含若干線程的ScheduledThreadPoolExecutor 適用於需要多個後台線程執行周期任務,同時為了滿足資源管理的需求而需要限制後台線程數量的應用場景。
只包含一個線程的SingleThreadScheduledExecutor                         適用於需要單個後台線程執行周期任務,同時需要保證順序的執行各個任務的場景。                                               
ForkJoinsPool

 newWorkStealingPool適合使用在很耗時的操作,但是newWorkStealingPool不是ThreadPoolExecutor的擴展,它是新的線程池類ForkJoinPool的擴展,但是都是在統一的一個Executors類中實現,由於能夠合理的使用CPU進行對任務操作(并行操作),所以適合使用在很耗時的任務中 

   
Future Future接口和實現了該接口的FutureTask類來表示異步計算的結果    
Runnable和Callable接口

Runnable和Callable接口的實現類,都可以被ThreadPoolExecutor、ScheduledThreadPool、ForkJoinThred執行;除了可以自己實現Callable接口外,我們還可以使用工廠類Executors來把一個Runnable包裝成一個Callable

   

 

ThreadPoolExecutor詳解

1、ThreadPoolExecutor

  (1)FixedThreadPool

  構造函數如下:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

  構造函數中,核心線程數和最大線程數一致,keepAliveTime為0,隊列使用的是無界阻塞隊列LinkedBlockingQueue(最大值是Integer.MAX_VALUE);

  核心線程數和最大線程數保持一致,表明:如果隊列滿了之後,不會再創建新的線程;

  keepAliveTime為0,表明:如果運行線程數大於核心線程數時,如果線程執行完畢,空閑線程立刻被終止;

  使用無界阻塞隊列,表明:當運行線程到達核心線程數時,不會再創建線程,只會將任務加入阻塞隊列;因此最大線程數參數無效;因此keepAliveTime參數無效;且不會拒絕任務(既不會執行包和策略)

  (2)SingleThreadExecutor

  構造函數如下:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

  構造函數中,核心線程數和最大線程數均為1,keepAliveTime為0,隊列使用的是無界阻塞隊列LinkedBlockingQueue(最大值是Integer.MAX_VALUE)

  除了固定了核心線程數和最大線程數為1外,其餘的參數均與FixedThreadPool一致,那麼就是只有一個線程會反覆循環從阻塞隊列中獲取任務執行

  (3)CacheThreadPool

  構造函數如下:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

  構造函數中,核心線程數為0,最大線程數為Integer.MAX_VALUE,意味着無界,keepAliveTime為60秒,阻塞隊列使用沒有存儲空間的SynchronousQueue

  核心線程數為0,最大線程數為無界,表明:只要隊列滿了,就會創建新的線程放入線程池

  使用沒有存儲空間的SynchronousQueue表明:線程提交的速度高於線程被消費的速度,那麼線程會被不斷的創建,最終會因為線程創建過多而耗盡CPU和內存資源

2、ScheduledThreadPoolExecutor

  ScheduledThreadPoolExecutor的運行機制如下:

   (1)當調用ScheduledTreadPoolExecutor的scheduleAtFixedRate()方法或者scheduleWithFixedDelay()方法時會向ScheduledThreadPoolExecutor的DelayQueue添加一個實現了RunnableScheduledFuture接口的ScheduledFutureTask

  (2)線程池中的線程從DelayQueue中獲取ScheduledFutureTask,然後執行任務。

  ScheduledFutureTask主要包含以下三個成員變量

成員變量 描述
long time 表示這個任務要被執行的時間
long sequenceNumber 表示該任務被添加到ScheduledThreadPoolExecutor中的序號
long period 表示任務執行的間隔周期

  DelayQueue封裝了一個PriorityQueue,當添加任務時,這個PriorityQueue會對隊列中的ScheduledFutureTask進行排序,time最小的在最前面(最先被執行),如果time一致,就比較sequenceNumber,sequenceNumber小的排在前面。

  當線程執行任務時,先從DelayQueue隊列中獲取已經到期的任務(time大於當前時間),然後執行該任務,執行完畢后,根據任務的執行周期,修改任務下次的執行時間time,並重新將任務添加到DelayQueue

 

 

  FutureTask詳解

  Future接口和實現該接口的FutureTask類,代表異步計算的結果。

  FutureTask的使用方法是將其交給Executor執行,也可以通過ExecutorService.submit()方法返回一個FutureTask,然後執行FutureTask.get()方法或FutureTask.cancel()方法,除此之外,還可以但是使用FutureTask。

  FutureTask有三種狀態:未啟動(FutureTask.run()沒有被執行之前的狀態)、已啟動(FutureTask.run()方法執行過程中)、已完成(FutureTask.run()方法執行完成或被取消),這三種狀態的流轉如下圖所示:

 

  FutureTask的實現是基於AQS(AbstractQueuedSynchrouizer)來實現的,之前已經說過,每一個基於AQS實現的同步器都會至少包含一個acquire操作和至少一個release操作。AQS被作為模板方法模式的基礎類提供給FutureTask的內部子類Sync實現了AQS的tryAcquireShared(int)方法和tryReleaseShared(int)方法,Sync通過這兩個方法來檢查和更新同步狀態。

  FutureTask涉及示意圖如下圖所示:

 

  如上圖所示,FutureTask.get()方法會調用AQS的acquireSharedInterruptibly(int)方法,該方法首先會回調在子類Sync中的tryAcquireShared()方法來判斷acquire操作是否成功(state狀態狀態是否為執行完成RAN或取消狀態CANCELED&runner不為null),如果成功則get()方法立刻返回,如果失敗則到線程等待隊列中去等待其他線程執行release操作;當其他線程執行release操作(比如FutureTask.run()或FutureTask.cancel())喚醒當前線程后,當前線程再次執行tryAcquireShared()將返回正值1,當前線程將離開線程等待隊列並喚醒它的後繼線程。

  Run方法執行過程如下:

  執行在構造函數中指定的任務(Callable.call()),然後以原子方式來更新狀態(調用AQS.compareAndSetState(int expect, int update),設置state的狀態為RAN),如果這個原子操作成功,就設置代表計算結果的變量result的值為Callable.call()的返回值,然後調用AQS.release(int)。

  AQS.rease首先會調用子類Sync中實現的tryReleaseShared方法來執行release操作(設置運行任務的線程為null,然後返回false),然後喚醒等待隊列中的第一個線程。

  最後調用Future.done()方法。

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※新北清潔公司,居家、辦公、裝潢細清專業服務