亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Spring中的線(xiàn)程池和定時(shí)任務(wù)功能

xeblog / 2121人閱讀

摘要:同時(shí)使用框架自己定義的抽象接口來(lái)屏蔽掉底層版本間以及中的線(xiàn)程池和定時(shí)任務(wù)處理的差異。配置文件如下所示完成配置后即可使用此線(xiàn)程池。

1.功能介紹

Spring框架提供了線(xiàn)程池和定時(shí)任務(wù)執(zhí)行的抽象接口:TaskExecutor和TaskScheduler來(lái)支持異步執(zhí)行任務(wù)和定時(shí)執(zhí)行任務(wù)功能。同時(shí)使用框架自己定義的抽象接口來(lái)屏蔽掉底層JDK版本間以及Java EE中的線(xiàn)程池和定時(shí)任務(wù)處理的差異。
另外Spring還支持集成JDK內(nèi)部的定時(shí)器Timer和Quartz Scheduler框架。

2.線(xiàn)程池的抽象:TaskExecutor

TaskExecutor涉及到的相關(guān)類(lèi)圖如下:

TaskExecutor接口源代碼如下所示:

public interface TaskExecutor extends Executor {

    /**
     * Execute the given {@code task}.
     * 

The call might return immediately if the implementation uses * an asynchronous execution strategy, or might block in the case * of synchronous execution. * @param task the {@code Runnable} to execute (never {@code null}) * @throws TaskRejectedException if the given task was not accepted */ @Override void execute(Runnable task); }

此接口和Executor幾乎完全一樣,只定義了一個(gè)接收Runnable參數(shù)的方法,據(jù)Spring官方介紹此接口最初是為了在其他組建中使用線(xiàn)程時(shí),將JKD抽離出來(lái)而設(shè)計(jì)的。在Spring的一些其他組件中比如ApplicationEventMulticaster,Quartz都是使用TaskExecutor來(lái)作為線(xiàn)程池的抽象的。

3.Spring提供的TaskExecutor的實(shí)現(xiàn)類(lèi)
org.springframework.core.task.SimpleAsyncTaskExecutor

此實(shí)現(xiàn)支持任務(wù)的異步執(zhí)行,但是此實(shí)現(xiàn)沒(méi)有線(xiàn)程的復(fù)用,每次執(zhí)行一個(gè)提交的任務(wù)時(shí)候都會(huì)新建一個(gè)線(xiàn)程,任務(wù)執(zhí)行完成后會(huì)將線(xiàn)程關(guān)閉,最大并發(fā)數(shù)默認(rèn)是沒(méi)有限制的,但是可以通過(guò)調(diào)用下面的方法來(lái)設(shè)置最大并發(fā)數(shù)。一般使用線(xiàn)程池來(lái)代替此實(shí)現(xiàn),特別是執(zhí)行一些生命周期很短的任務(wù)的時(shí)候。

public void setConcurrencyLimit(int concurrencyLimit) {
        this.concurrencyThrottle.setConcurrencyLimit(concurrencyLimit);
    }

Spring還提供了同步任務(wù)執(zhí)行的實(shí)現(xiàn)類(lèi):

  org.springframework.core.task.SyncTaskExecutor

此類(lèi)中只有一個(gè)方法,代碼如下:

@Override
    public void execute(Runnable task) {
        Assert.notNull(task, "Runnable must not be null");
        task.run();
    }

此方法中直接調(diào)用傳入的Runable對(duì)象的run方法,因此在執(zhí)行此方法的時(shí)候不會(huì)另外開(kāi)啟新的線(xiàn)程,只是普通的方法調(diào)用,同步執(zhí)行提交的Runable對(duì)象。
Spring有兩個(gè)線(xiàn)程池的實(shí)現(xiàn)類(lèi),分別為:SimpleThreadPoolTaskExecutor和ThreadPoolTaskExecutor,其中當(dāng)我們有Quarts和非Quarts共享同一個(gè)線(xiàn)程池的需求的時(shí)候使用SimpleThreadPoolTaskExecutor,除了這種情況,我們一般是使用
ThreadPoolTaskExecutor,此實(shí)現(xiàn)可以通過(guò)屬性注入來(lái)配置線(xiàn)程池的相關(guān)配置。 ThreadPoolTaskExecutor中屬性注入的源碼如下:此配置可以在運(yùn)行期修改,代碼中修改過(guò)程使用了同步控制。

/**
 * Set the ThreadPoolExecutor"s core pool size.
 * Default is 1.
 * 

This setting can be modified at runtime, for example through JMX. */ public void setCorePoolSize(int corePoolSize) { synchronized (this.poolSizeMonitor) { this.corePoolSize = corePoolSize; if (this.threadPoolExecutor != null) { this.threadPoolExecutor.setCorePoolSize(corePoolSize); } } }

4.TaskExecutor使用Demo

首先定義一個(gè)任務(wù)如下所示:

public class DataSimulation implements Runnable{

  private HourAverageValueDao hourAverageValueDao;

  @Override
  public void run() {

      Random random = new Random();
      AverageValue averageValue = new AverageValue();
      averageValue.setAverageVaule(random.nextInt(100));
      averageValue.setCreatedTime(new Date());
      hourAverageValueDao.insert(averageValue);

  }
}

此任務(wù)中產(chǎn)生一個(gè)隨機(jī)數(shù),并封裝成一個(gè)類(lèi)對(duì)象,并將此數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中。
然后需要定一個(gè)類(lèi),使用TaskExecutor,代碼如下:

public class DataFacotory {

    private TaskExecutor executor;

    public TaskExecutor getExecutor() {
        return executor;
    }

    public void setExecutor(TaskExecutor executor) {
        this.executor = executor;
    }

    public void dataFactory(){

        for (int i =0; i < 10; i++){
            executor.execute(new DataSimulation());
        }
    }
}

此類(lèi)中定義了TaskExecutor的屬性,并定一個(gè)方法,此方法中提交10個(gè)任務(wù)到TaskExecutor,下面只需配置Spring文件,注入TaskExecutor就可以實(shí)現(xiàn)線(xiàn)程池的使用。配置文件如下所示:


      
      
      
  

完成配置后即可使用此線(xiàn)程池。Spring提供的線(xiàn)程池可以通過(guò)配置文件配置線(xiàn)程池的配置,相比JDk自帶的線(xiàn)程池是一個(gè)很大的優(yōu)勢(shì)。

5.為什么使用線(xiàn)程池

1.通過(guò)使用線(xiàn)程池來(lái)實(shí)現(xiàn)線(xiàn)程的復(fù)用,減少線(xiàn)程創(chuàng)建和銷(xiāo)毀的開(kāi)銷(xiāo)
2.將執(zhí)行線(xiàn)程的任務(wù)交給線(xiàn)程池來(lái)操作,一定意義上實(shí)現(xiàn)了解耦
3.使用線(xiàn)程池可以控制任務(wù)的最大并發(fā)數(shù)目,這個(gè)在防止內(nèi)存溢出以及并發(fā)優(yōu)化方面有很重要的作用。

6.定時(shí)任務(wù)抽象類(lèi):TaskScheduler

TaskScheduler接口源代碼如下:

public interface TaskScheduler {
  //通過(guò)觸發(fā)器來(lái)決定task是否執(zhí)行
ScheduledFuture schedule(Runnable task, Trigger trigger);
//在starttime的時(shí)候執(zhí)行一次
ScheduledFuture schedule(Runnable task, Date startTime);
從starttime開(kāi)始每個(gè)period時(shí)間段執(zhí)行一次task
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
每隔period執(zhí)行一次
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
從startTime開(kāi)始每隔delay長(zhǎng)時(shí)間執(zhí)行一次
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
每隔delay時(shí)間執(zhí)行一次
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);

}

指定開(kāi)始時(shí)間的接口,如果時(shí)間已經(jīng)是過(guò)去的某一時(shí)間點(diǎn),則此任務(wù)會(huì)馬上執(zhí)行一次。以上幾種執(zhí)行方式傳入Trigger的方式是用的最多的,Trigger接口中只定義了一個(gè)方法:

Date nextExecutionTime(TriggerContext triggerContext);

其中參數(shù)類(lèi)型TriggerContext的定義如下:

public interface TriggerContext {

  /**
   * Return the last scheduled execution time of the task,
   * or {@code null} if not scheduled before.
   */
  Date lastScheduledExecutionTime();

  /**
   * Return the last actual execution time of the task,
   * or {@code null} if not scheduled before.
   */
  Date lastActualExecutionTime();

  /**
   * Return the last completion time of the task,
   * or {@code null} if not scheduled before.
   */
  Date lastCompletionTime();

}

提供了獲取上一次任務(wù)執(zhí)行信息的接口。我們通過(guò)實(shí)現(xiàn)Trigger接口可以實(shí)現(xiàn)自定義觸發(fā)器來(lái)執(zhí)行執(zhí)行task。當(dāng)然Spring也提供了兩個(gè)默認(rèn)的實(shí)現(xiàn)類(lèi):PeriodicTrigger和CronTrigger。

7.TaskScheduler定時(shí)任務(wù)Demo

首先在Spring配置文件中啟用注解配置如下:

 //指定scheduler屬性是可選項(xiàng),不添加也可以正常使用

然后創(chuàng)建service,并在service中使用@Scheduled注解創(chuàng)建定時(shí)任務(wù),代碼如下:

@Component
public class SchedulerPoolTest {

  @Scheduled(cron = "0 * * * * ?")
  public void task1(){
      System.out.println("test");
      Thread thread =  Thread.currentThread();
      System.out.println("ThreadName:" + thread.getName() + ",id:" + thread.getId() + ",group:" + thread.getThreadGroup());

  }

  @Scheduled(fixedDelay = 5000)
  public void task2(){
      System.out.println("test");
      Thread thread =  Thread.currentThread();
      System.out.println("ThreadName:" + thread.getName() + ",id:" + thread.getId() + ",group:" + thread.getThreadGroup());

  }

}

只是添加以上內(nèi)容可能還不能正常執(zhí)行task,還需要注意以下兩點(diǎn):

1.必須將SchedulerPoolTest類(lèi)包含在spring所掃描的包里面
配置如下:


2.需要在web.xml中添加spring配置文件的監(jiān)聽(tīng)器,代碼如下:


 contextConfigLocation
 classpath*:spring-task.xml
 

 
   org.springframework.web.context.ContextLoaderListener
 

添加以上內(nèi)容后,啟動(dòng)服務(wù)器,將會(huì)定時(shí)執(zhí)行任務(wù)。

8.Cron表達(dá)式

Cron表達(dá)式由6個(gè)字符串組成,每個(gè)字符串分別代表:

{秒} {分} {時(shí)} {日} {月} {周}

其中每個(gè)字符串所允許的取值范圍為:

字段名                 允許的值                        允許的特殊字符  
秒                    0-59                            , - * /  
分                    0-59                            , - * /  
小時(shí)                  0-23                            , - * /  
日                    1-31                            , - * ? / L W C  
月                    1-12 or JAN-DEC                 , - * /  
周幾                  1-7 or SUN-SAT                   , - * ? / L C #

常用的Cron表達(dá)式:

"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44觸發(fā)
"0 0/5 14,18 * * ?" 在每天下午2點(diǎn)到2:55期間和下午6點(diǎn)到6:55期間的每5分鐘觸發(fā)
"15-30/5 * * * * ?" 每分鐘的15秒到30秒之間開(kāi)始觸發(fā),每隔5秒觸發(fā)一次
"0 15 10 ? * 5#3" 每個(gè)月第三周的星期四的10點(diǎn)15分0秒觸發(fā)任務(wù)

注:?jiǎn)柼?hào)是用于避免日和周的設(shè)定由沖突而用的,當(dāng)其中一個(gè)設(shè)置了具體的值,另外一個(gè)必須使用?。另外推薦一個(gè)Cron表達(dá)式生成的鏈接:http://www.cronmaker.com/

9.@Async注解

Async注解提供了異步調(diào)用方法的功能,當(dāng)調(diào)用由此注解的方法的時(shí)候方法調(diào)用者會(huì)馬上返回而不會(huì)等待調(diào)用的方法執(zhí)行完成,被調(diào)用的方法會(huì)從線(xiàn)程池中分配一個(gè)線(xiàn)程來(lái)執(zhí)行此方法。

10.Spring定時(shí)任務(wù)中并發(fā)執(zhí)行的問(wèn)題

同一個(gè)任務(wù),當(dāng)上一個(gè)任務(wù)沒(méi)有執(zhí)行完成的時(shí)候,新的任務(wù)不會(huì)執(zhí)行。
不同任務(wù)的情況下:TODO...

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70398.html

相關(guān)文章

  • Spring定時(shí)任務(wù)高級(jí)使用篇

    摘要:定時(shí)任務(wù)高級(jí)使用篇前面一篇博文之定時(shí)任務(wù)基本使用篇介紹了環(huán)境下,定時(shí)任務(wù)的簡(jiǎn)單使用姿勢(shì),也留了一些問(wèn)題,這一篇?jiǎng)t希望能針對(duì)這些問(wèn)題給個(gè)答案定時(shí)任務(wù)進(jìn)階篇問(wèn)題小結(jié)前面一篇博文,拋出了下面的幾個(gè)問(wèn)題,接下來(lái)則圍繞問(wèn)題進(jìn)行分析一個(gè)項(xiàng)目中有多個(gè)定時(shí) showImg(https://segmentfault.com/img/remote/1460000015880327); Spring定時(shí)任務(wù)...

    dcr309duan 評(píng)論0 收藏0
  • SpringBoot中并發(fā)定時(shí)任務(wù)的實(shí)現(xiàn)、動(dòng)態(tài)定時(shí)任務(wù)的實(shí)現(xiàn)(看這一篇就夠了)

    摘要:也是自帶的一個(gè)基于線(xiàn)程池設(shè)計(jì)的定時(shí)任務(wù)類(lèi)。其每個(gè)調(diào)度任務(wù)都會(huì)分配到線(xiàn)程池中的一個(gè)線(xiàn)程執(zhí)行,所以其任務(wù)是并發(fā)執(zhí)行的,互不影響。 原創(chuàng)不易,如需轉(zhuǎn)載,請(qǐng)注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責(zé)任?。?! 一、在JAVA開(kāi)發(fā)領(lǐng)域,目前可以通過(guò)以下幾種方式進(jìn)行定時(shí)任務(wù) 1、單機(jī)部署模式 Timer:jdk中...

    BWrong 評(píng)論0 收藏0
  • Spring Boot(四)Spring Boot 中的定時(shí)任務(wù)

    摘要:對(duì)于定時(shí)任務(wù)類(lèi)如果不定義線(xiàn)程池,控制臺(tái)輸出如下,可以看到不同的定時(shí)任務(wù)是同一個(gè)線(xiàn)程在執(zhí)行在配置類(lèi)或者啟動(dòng)類(lèi)中增加定時(shí)任務(wù)的線(xiàn)程池控制臺(tái)輸出本節(jié)示例代碼已上傳到 一.SpringBoot中開(kāi)啟定時(shí)任務(wù) 在spirngboot中使用定時(shí)任務(wù)非常簡(jiǎn)單,只需要在啟動(dòng)類(lèi)上增加一個(gè)@EnableScheduling注解即可。 @SpringBootApplication @EnableSchedu...

    firim 評(píng)論0 收藏0
  • Spring 定時(shí)任務(wù)

    摘要:在定時(shí)器接口的方法中我們可以發(fā)現(xiàn)一個(gè)方法接受接口,而也是一個(gè)接口,抽象了觸發(fā)任務(wù)執(zhí)行的觸發(fā)器。更常用的一個(gè)觸發(fā)器是,它使用表達(dá)式指定何時(shí)執(zhí)行任務(wù)。配置定時(shí)任務(wù)首先看看配置。配置提供了命名空間,讓配置定時(shí)任務(wù)非常簡(jiǎn)單。 本文參考自Spring官方文檔 34. Task Execution and Scheduling。 在程序中常常有定時(shí)任務(wù)的需求,例如每隔一周生成一次報(bào)表、每個(gè)月月末清...

    justCoding 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<