Java并發編程之線程定時器ScheduledThreadPoolExecutor解析

定時器

就是需要周期性的執行任務,也叫調度任務,在JDK中有個類Timer是支持周期性執行,但是這個類不建議使用了。

ScheduledThreadPoolExecutor

繼承自ThreadPoolExecutor線程池,在Executors默認創建了兩種:

newSingleThreadScheduledExecutor:只包含一個線程,只需要單個線程執行周期任務,保證順序的執行各個任務。

newScheduledThreadPool: 可以包含多個線程的,線程執行周期任務,適度控制后臺線程數量的時候。

方法:

schedule:只執行一次,任務還可以延時執行

scheduleAtFixedRate:提交固定時間間隔的任務

scheduleWithFixedDelay:提交固定延時間隔執行的任務

兩者的區別:間隔的時間定義不一樣

建議在提交給ScheduledThreadPoolExecutor的任務要住catch異常。否則不能周期性執行任務。

基本原理

在之前將BlockingQueue<T>的時候有個叫DelayQueue<E extends Delayed>堵塞隊列,這個就是實現延遲執行,在ScheduledThreadPoolExecutor實現時間間隔執行的原理與DelayQueue原理差不多

在ScheduledThreadPoolExecutor中有個靜態類DelayedWorkQueue,該類也是一個延時隊列。

構造方法是調用了父類構造,將隊列換成了延時隊列DelayedWorkQueue

    public ScheduledThreadPoolExecutor(int corePoolSize,RejectedExecutionHandler handler) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue(), handler);}

在ThreadPoolExecutor談到了獲取隊列中Runnable對象即執行take方法,看一下DelayedWorkQueue的take()方法,在延時是調用了Condition的awaitNanos()方法進行延時執行,

    private final Condition available = lock.newCondition();    public RunnableScheduledFuture<?> take() throws InterruptedException {final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {for (;;) {RunnableScheduledFuture<?> first = queue[0];if (first == null)available.await();else {long delay = first.getDelay(NANOSECONDS);if (delay <= 0)return finishPoll(first);first = null; // don't retain ref while waitingif (leader != null)available.await();else {Thread thisThread = Thread.currentThread();leader = thisThread;try {available.awaitNanos(delay);} finally {if (leader == thisThread)leader = null;}}}}} finally {if (leader == null && queue[0] != null)available.signal();lock.unlock();}}

周期性執行是在執行完后會再次將當前任務放入到線程池中,再次等待延時執行。

//在調用scheduleAtFixedRate()方法是會調用delayedExecute方法將當前Runnable對象添加到隊列當中
//等待執行  
private void delayedExecute(RunnableScheduledFuture<?> task) {if (isShutdown())reject(task);else {super.getQueue().add(task);if (isShutdown() &&!canRunInCurrentRunState(task.isPeriodic()) &&remove(task))task.cancel(false);elseensurePrestart();}}        
//在ScheduledFutureTask中,當線程池調用好了Runnable對象的run方法的時候,會調用reExecutePeriodic()方法將任務再次放入到線程池中,所以如果在執行報錯了,那么就不會放入到線程池中,/*** Overrides FutureTask version so as to reset/requeue if periodic.*/public void run() {boolean periodic = isPeriodic();if (!canRunInCurrentRunState(periodic))cancel(false);else if (!periodic)ScheduledFutureTask.super.run();else if (ScheduledFutureTask.super.runAndReset()) {setNextRunTime();reExecutePeriodic(outerTask);}}

CompletionService

這個類了解一下就好了,在使用Future并發執行的時候一般都是將多個Future對象用數組或集合保存起來,然后在循環數組或集合調用get方法獲取結果集,但是如果使用了CompletionService會將率先執行的結果集獲取到,就是利用了堵塞隊列原理實現的這種效果

用法:

		ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);CompletionService<String> completionService = new ExecutorCompletionService<String>(newFixedThreadPool);completionService.submit(new Callable<String>() {@Overridepublic String call() throws Exception {return null;}});completionService.take().get();

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537157.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537157.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537157.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python xml轉換鍵值對_Python 提取dict轉換為xml/json/table并輸出

#!/usr/bin/python#-*- coding:gbk -*-#設置源文件輸出格式import sysimport getoptimport jsonimport createDictimport myConToXMLimport myConToTabledef getRsDataToDict():#獲取控制臺中輸入的參數&#xff0c;并根據參數找到源文件獲取源數據csDict{}try:#通過getopt獲取…

應用開發框架之——根據數據表中的存儲的方法名稱來調用方法

功用一&#xff1a;在框架里面根據存儲在數據表中的方法名來動態調用執行方法。 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 class(TForm) Button1: TButton; procedu…

Spring IOC容器組件注入的幾種方式

整理一下之前Spring的學習筆記&#xff0c;大致有一下幾種Spring注入到容器中的方法: 1&#xff09;、配置在xml的方式。 2&#xff09;、開啟包掃描ComponentScan使用Component&#xff0c;Service&#xff0c;Controller&#xff0c;Repository&#xff08;其實后三個都繼承…

我們是如何拿下Google和Facebook Offer的?

http://posts.careerengine.us/p/57c3a1c1a09633ee7e57803c 大家好&#xff0c;我是小高&#xff0c;CMU CS Master&#xff0c;來Offer第一期學員&#xff0c;2014年初在孫老師的帶領下我在幾個月的時間內進入了Yahoo&#xff0c;并工作了近2年。2016年初&#xff0c;Yahoo工作…

Spring中BeanFactory和FactoryBean的區別

先介紹一下Spring的IOC容器到底是個什么東西&#xff0c;都說是一個控制反轉的容器&#xff0c;將對象的控制權交給IOC容器&#xff0c;其實在看了源代碼之后&#xff0c;就會發現IOC容器只是一個存儲單例的一個ConcurrentHashMap<String, BeanDefinition> BeanDefiniti…

python中數字和字符串可以直接相加_用c語言或者python將文件中特定字符串后面的數字相加...

匿名用戶1級2014-08-31 回答代碼應該不難吧。既然用爬蟲爬下來了&#xff0c;為什么爬取數據的時候沒做處理呢。之前用過Scrapy爬蟲框架&#xff0c;挺好用的&#xff0c;你可研究下。代碼&#xff1a;#!codingutf-8import osimport reimport random# 獲取當前目錄文件列表def …

Spring中Aware的用法以及實現

Aware 在Spring當中有一些內置的對象是未開放給我們使用的&#xff0c;例如Spring的上下文ApplicationContext、環境屬性Environment&#xff0c;BeanFactory等等其他的一些內置對象&#xff0c;而在我們可以通過實現對應的Aware接口去拿到我們想要的一些屬性&#xff0c;一般…

c#字符型轉化為asc_C#字符串和ASCII碼的轉換

//字符轉ASCII碼&#xff1a;public static int Asc(string character){if (character.Length 1){System.Text.ASCIIEncoding asciiEncoding new System.Text.ASCIIEncoding();int intAsciiCode (int)asciiEncoding.GetBytes(character)[0];return (intAsciiCode);}else{thr…

topcoder srm 625 div1

problem1 link 假設第$i$種出現的次數為$n_{i}$&#xff0c;總個數為$m$&#xff0c;那么排列數為$T\frac{m!}{\prod_{i1}^{26}(n_{i}!)}$ 然后計算回文的個數&#xff0c;只需要考慮前一半&#xff0c;得到個數為$R$&#xff0c;那么答案為$\frac{R}{T}$. 為了防止數字太大導致…

Spring的組件賦值以及環境屬性@PropertySource

PropertySource 將指定類路徑下的.properties一些配置加載到Spring當中&#xff0c; 有個跟這個差不多的注解PropertySources Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented public interface PropertySources {PropertySource[] value();} 使用…

python語音識別框架_橫評:五款免費開源的語音識別工具

編者按&#xff1a;本文原作者 Cindi Thompson&#xff0c;美國德克薩斯大學奧斯汀分校(University of Texas at Austin)計算機科學博士&#xff0c;數據科學咨詢公司硅谷數據科學(Silicon Valley Data Science&#xff0c;SVDS)首席科學家&#xff0c;在機器學習、自然語言處理…

csharp read excel file get sheetName list

1 /// <summary>2 /// 3 /// 塗聚文4 /// 201208035 /// Geovin Du6 ///找到EXCEL的工作表名稱 要考慮打開的文件的進程問題7 /// </summary>8 /// <param name"filename">…

Spring Bean的生命周期以及IOC源碼解析

IOC源碼這一塊太多只能講個大概吧&#xff0c;建議還是去買本Spring IOC源碼解析的書來看比較好&#xff0c;我也是自己看源代碼以及視頻整理的筆記 Bean的生命周期大概可以分為四個階段&#xff0c;具體的等會再說&#xff0c;先看看IOC的源碼吧 1、bean的創建 2、bean的屬…

python3繪圖_python3繪圖示例2(基于matplotlib:柱狀圖、分布圖、三角圖等)

#!/usr/bin/env python# -*- coding:utf-8 -*-from matplotlib import pyplot as pltimport numpy as npimport pylabimport os,sys,time,math,random# 圖1-給已有的圖加上刻度filer‘D:\jmeter\jmeter3.2\data\Oracle數據庫基礎.png‘arrnp.array(file.getdata()).reshape(fil…

bzoj4152-[AMPPZ2014]The_Captain

Description 給定平面上的n個點&#xff0c;定義(x1,y1)到(x2,y2)的費用為min(|x1-x2|,|y1-y2|)&#xff0c;求從1號點走到n號點的最小費用。 Input 第一行包含一個正整數n(2<n<200000)&#xff0c;表示點數。 接下來n行&#xff0c;每行包含兩個整數x[i],yi&#xff0c;…

python日志統計_python試用-日志統計

最近兩天嘗試用python代替bash寫Linux Shell腳本來統計日志。發現python寫起來比bash更簡單和容易閱讀&#xff0c;發現不少驚喜。所以寫了一個粗糙的腳本來統計日志。目標1、通過簡單命令和腳本統計事件發生數2、日志限定文本類型假定環境日志文件&#xff1a;1.logtest:aaa,1…

Spring AOP兩種使用方式以及如何使用解析

AOP是一種面向切面編程思想&#xff0c;也是面向對象設計&#xff08;OOP&#xff09;的一種延伸。 在Spring實現AOP有兩種實現方式&#xff0c;一種是采用JDK動態代理實現&#xff0c;另外一種就是采用CGLIB代理實現&#xff0c;Spring是如何實現的在上篇已經講到了Spring Be…

如何用python生成可執行程序必須經過_python怎么生成可執行文件

.py文件&#xff1a;對于開源項目或62616964757a686964616fe58685e5aeb931333363393664者源碼沒那么重要的&#xff0c;直接提供源碼&#xff0c;需要使用者自行安裝Python并且安裝依賴的各種庫。(Python官方的各種安裝包就是這樣做的).pyc文件&#xff1a;有些公司或個人因為機…

Jmeter 老司機帶你一小時學會Jmeter

Jmeter的安裝 官網下載地址&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 作為Java應用&#xff0c;是需要JDK環境的&#xff0c;因此需要下載安裝JAVA&#xff0c;并且作必要的的環境變量配置。 一、bin目錄 examples:    目錄中有CSV樣例 jmeter.bat/jmeter…