91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring任務執行和調度的示例分析

發布時間:2021-08-25 09:23:36 來源:億速云 閱讀:114 作者:小新 欄目:編程語言

這篇文章主要為大家展示了“Spring任務執行和調度的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Spring任務執行和調度的示例分析”這篇文章吧。

一、概述

Spring框架分別使用TaskExecutor和TaskScheduler接口提供異步執行和任務調度的抽象。Spring還提供了這些接口的實現,這些接口支持線程池或將其委托給應用服務器環境中的CommonJ。

二、TaskExecutor

Spring 2.0 開始引入的新的抽像。Executors 是線程池的Java 5名稱。之所以稱作是“執行器”是因為不能保證底層實現實際上是一個池;執行程序可以是單線程的,甚至是同步的。Spring的TaskExecutor接口與java.util.concurrent是等價的。

2.1 TaskExecutor類型

SimpleAsyncTaskExecutor

線程不會重用,每次調用開啟一個新的線程。支持并發,超過最大并發調用數時,會阻塞,直到釋放一個槽為止。

SyncTaskExecutor

不會異步執行調用。每次調用都發生在調用線程中。它主要用于不需要多線程的情況。

ConcurrentTaskExecutor

Java 5 Java .util.concurrent. executor的包裝。替代方案是ThreadPoolTaskExecutor,它將Executor配置參數作為bean屬性公開。很少使用。

SimpleThreadPoolTaskExecutor

Quartz的SimpleThreadPool的一個子類,它監聽Spring的生命周期回調。Quartz組件和非Quartz組件共享需要共享一個線程池時,通常會使用這種方法。

ThreadPoolTaskExecutor

只能在java5中使用。公開了用于配置java.util.concurrent的bean屬性。如果需要高級的東西,比如ScheduledThreadPoolExecutor,建議使用ConcurrentTaskExecutor替代。

TimerTaskExecutor

通過TimerTask支撐實現。 不同于SyncTaskExecutor,因為方法調用在一個單獨的線程中執行,盡管它們在那個線程中是同步的。

WorkManagerTaskExecutor

使用CommonJ WorkManager作為它的支持實現,并且是在Spring上下文中設置CommonJ WorkManager引用的中心便利類。與SimpleThreadPoolTaskExecutor類似,這個類實現了WorkManager接口,因此也可以直接作為WorkManager使用。

2.2 使用 TaskExecutor

public class TaskExecutorExample {
 private class MessagePrinterTask implements Runnable {
  private String message;
  public MessagePrinterTask(String message) {
   this.message = message;
  }
  public void run() {
   System.out.println(message);
  }
 }
 private TaskExecutor taskExecutor;
 public TaskExecutorExample(TaskExecutor taskExecutor) {
  this.taskExecutor = taskExecutor;
 }
 public void printMessages() {
  for (int i = 0; i < 25; i++) {
   taskExecutor.execute(new MessagePrinterTask("Message" + i));
  }
 }
}

與其從池中檢索線程并自己執行,不如將Runnable添加到隊列中,而TaskExecutor使用其內部規則來決定任務何時執行

配置TaskExecutor將使用的規則

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent
.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
<bean id="taskExecutorExample" class="cn.pconline.activity.task.TaskExecutorExample" init-method="printMessages">
<constructor-arg ref="taskExecutor" />
</bean>

三、TaskScheduler

除了任務執行者抽象之外。Spring 3.0還引入了一個TaskScheduler,它有多種方法來調度未來某個時候運行的任務。

public interface TaskScheduler {
 ScheduledFuture schedule(Runnable task, Trigger trigger);
 ScheduledFuture schedule(Runnable task, Date startTime);
 ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
 ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
 ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
 ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}

名為“schedule”的方法,它只接受可運行的日期。這將導致任務在指定時間后運行一次。

所有其他方法都能夠安排任務重復運行。固定速率和固定延遲方法用于簡單的、周期性的執行,但是使用 Trigger 的方法要靈活得多。

3.1 Trigger

觸發器的基本思想是,執行時間可以根據過去的執行結果甚至任意條件來確定。如果這些決定確實考慮了前面執行的結果,那么該信息在TriggerContext中是可用的。

public interface Trigger {
 Date nextExecutionTime(TriggerContext triggerContext);
}
public interface TriggerContext {
 Date lastScheduledExecutionTime();
 Date lastActualExecutionTime();
 Date lastCompletionTime();
}

TriggerContext是最重要的部分。它封裝了所有相關的數據,如果有必要,將來還可以進行擴展。TriggerContext是一個接口(默認情況下使用SimpleTriggerContext實現)。

3.2 Trigger 實現

Spring提供了觸發器接口的兩個實現。最有趣的是CronTrigger。它支持基于cron表達式的任務調度。

scheduler.schedule(task, new CronTrigger(" 15 9-17 * MON-FRI"));

另一個開箱即用的實現是一個周期性Trigger ,它接受一個固定的周期、一個可選的初始延遲值,以及一個布爾值,用來指示周期應該解釋為固定速率還是固定延遲。由于TaskScheduler接口已經定義了以固定速率或固定延遲調度任務的方法,因此應該盡可能直接使用這些方法。PeriodicTrigger實現的價值在于它可以在依賴于觸發器抽象的組件中使用。例如,允許周期性Trigger 、基于cro的Trigger ,甚至自定義Trigger 實現可以互換使用,這可能很方便。這樣的組件可以利用依賴注入,這樣就可以在外部配置這樣的Trigger 。

3.3 TaskScheduler實現

在應用服務器環境中,TaskScheduler提供的靈活性尤其重要。因為在這種環境中,線程不應該由應用程序本身直接創建。對于這種情況,Spring提供了一個TimerManagerTaskScheduler,它將委托給CommonJ TimerManager實例,通常配置為JNDI-lookup。

四、調度和異步執行的注解支持

4.1 開啟scheduling 注解功能

為了支持@Scheduled和@Async注釋,請將@EnableScheduling和@EnableAsync添加到@Configuration類中

@Configuration
@EnableAsync
@EnableSCheduling
public class AppConfig {
}

你可以自由選擇應用程序的相關注釋。例如,如果只需要支持@Scheduled,那么只需省略@EnableAsync即可。對于更細粒度的控制,可以另外實現調度器和/或AsyncConfigurer接口。

如果你更喜歡xml配置,這樣配置。

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>}

4.2 @Scheduled

@Scheduled添加到方法上

//上一次調用完之后,五秒再調用一次,依此循環下去
@Scheduled(fixedDelay=5000)
public void doSomething() {
 // something that should execute periodically
}
//連續的每次調用開始時間之間,間隔5s
@Scheduled(fixedRate=5000)
public void doSomething() {
 // something that should execute periodically
}
//
@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
 // something that should execute on weekdays only
}

值得注意的是調度的方法返回值必須是void,并且不能期望有任何參數。如果方法需要與來自應用程序上下文的其他對象交互,那么這些對象通常是通過依賴注入提供的。

4.3 @Async注解

添加了@Async注解的方法會異步執行。換句話說,方法調用后會立即返回,方法的實際執行將發生在提交給Spring TaskExecutor的任務中。

@Async
void doSomething() {
 // this will be executed asynchronously
}
/@Scheduled注釋的方法不同,這些方法可以預期參數.
//因為調用方將在運行時以“正常”方式調用它們,而不是從容器管理的調度任務中調用。
@Async
void doSomething(String s) {
 // this will be executed asynchronously
}
// 具有Future回調返回值
//執行其它任務的優先級 依然是高于執行回調的優先級。
@Async
Future<String> returnSomething(int i) {
 // this will be executed asynchronously
}

4.4 指定@Async注解的執行器

默認情況下,在方法上指定@Async時,將使用的執行器是提供“annotation-driven”元素的執行器,如上所述。然而,當需要指示在執行給定方法時應該使用非默認的執行器時,可以使用@Async注釋的值屬性。

@Async("otherExecutor")
void doSomething(String s) {
 // this will be executed asynchronously by "otherExecutor"
}

五、Task 命名空間

從Spring 3.0開始,有一個用于配置TaskExecutor和TaskScheduler實例的XML名稱空間。并提供了一種方便的方法,可以將任務配置為使用觸發器進行調度。

5.1 scheduler 元素

<!-- 默認創建一個指定大小的ThreadPoolTaskScheduler -->
<task:scheduler id="scheduler" pool-size="10"/>

id屬性用作線程池中線程的前綴名。如果不指定pool-size,默認的線程池中只有一個線程。

5.2 executor元素

<!-- 創建ThreadPoolTaskExecutor實例 -->
<task:executor id="executor" pool-size="10"/>

與上面的調度器一樣,為'id'屬性提供的值將用作池中線程名稱的前綴。就池大小而言,'executor'元素比'scheduler'元素支持更多的配置選項。首先,ThreadPoolTaskExecutor的線程池本身是可配置的。執行程序的線程池可能對核心和最大大小有不同的值,而不僅僅是單個大小。如果提供了單個值,那么執行器將擁有一個固定大小的線程池(核心和最大大小相同)。然而,“executor”元素的“池大小”屬性也接受“min-max”形式的范圍。

<task:executor id="executorWithPoolSizeRange"
pool-size="5-25"
queue-capacity="100"/><!-- 指定隊列的大小-->
<task:executor id="executorWithCallerRunsPolicy"
pool-size="5-25"
queue-capacity="100"
rejection-policy="CALLER_RUNS"/><!-- 任務拒絕策略(強制任務提交線程執行任務,從而限制傳入負載變得過大) 默認的是直接拋出異常-->

5.3 scheduled-tasks元素

Spring task namespace 最強大的特性是支持在Spring應用程序上下文中配置要調度的任務。這與Spring中的其他“方法調用者”類似,例如JMS名稱空間提供的配置消息驅動pojo的方法。

<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="beanA" method="methodA" fixed-delay="5000"/><!--ref
指向容器管理的對象,method是要執行的方法名-->
</task:scheduled-tasks>
<task:scheduler id="myScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="beanA" method="methodA" fixed-delay="5000" initial-delay="1000"/><!--第一次執行延遲一秒,以后每次上一個任務完成后 再執行-->
<task:scheduled ref="beanB" method="methodB" fixed-rate="5000"/>
<!--固定頻率執行 如果上一個任務執行時間超時,第二個任務會立即執行 -->
<task:scheduled ref="beanC" method="methodC" cron="*/5 * * * * MON-FRI"/>
</task:scheduled-tasks>
<task:scheduler id="myScheduler" pool-size="10"/>

六、Quartz Scheduler

Quartz使用觸發器、作業和作業細節對象來實現各種作業的調度。有關Quartz背后的基本概念,請參閱http://quartz-scheduling er.org。為了方便起見,Spring提供了兩個類,它們簡化了基于Spring的應用程序中Quartz的使用。

6.1 使用JobDetailBean

JobDetail對象包含運行作業所需的所有信息。Spring框架提供了JobDetailBean,它使JobDetail更接近于具有合理默認值的實際JavaBean。

<bean name="exampleJob" class="org.springframework.scheduling
.quartz.JobDetailBean">
<property name="jobClass" value="example.ExampleJob" />
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="5" />
</map>
</property>
</bean>

job detail bean 具有運行作業(ExampleJob)所需的所有信息。timeout在job data map指定。job data map可以通過JobExecutionContext(在執行時傳遞給您)獲得,但是JobDetailBean還將 job data map 中的屬性映射到實際job的屬性。因此,在本例中,如果ExampleJob包含一個名為timeout的屬性,JobDetailBean將自動應用它。

package example;
public class ExampleJob extends QuartzJobBean {
 private int timeout;
 /**
* Setter called after the ExampleJob is instantiated
* with the value from the JobDetailBean (5)
*/
 public void setTimeout(int timeout) {
  this.timeout = timeout;
 }
 protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
  // do the actual work
 }
}

6.2 使用MethodInvokingJobDetailFactoryBean

使用MethodInvokingJobDetailFactoryBean你可以調用特定對象上的方法。

<bean id="jobDetail" class="org.springframework.scheduling.quartz
.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject" />
<property name="targetMethod" value="doIt" />
</bean>
<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>

使用上面的配置將會導致ExampleBusinessObject .doIt()方法被調用。

public class ExampleBusinessObject {
 // properties and collaborators
 public void doIt() {
  // do the actual work
 }
}

使用MethodInvokingJobDetailFactoryBean,不再需要創建只調用一個方法的一行作業,只需要創建實際的業務對象并連接到它。

默認情況下,Quartz作業是無狀態的,導致作業相互干擾的可能性。如果為相同的JobDetail指定兩個觸發器,那么可能在第一個作業完成之前,第二個作業就會開始。如果JobDetail類實現有狀態接口,則不會發生這種情況。在第一項工作完成之前,第二項工作不會開始。要使方法調用jobdetailfactorybean產生的作業非并發,請將并發標志設置為false。

<bean id="jobDetail" class="org.springframework.scheduling.quartz
.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject" />
<property name="targetMethod" value="doIt" />
<property name="concurrent" value="false" />
<!--并發執行false-->
</bean>

6.3 作業調度

盡管我們能使用MethodInvokingJobDetailFactoryBean調用特定對象上的方法,但是我們還是需要調度作業 。這需要使用觸發器和scheduler erfactorybean完成。Quartz 提供了多種觸發器

Spring提供了兩種Quartz 工廠對象:

  • CronTriggerFactoryBean

  • SimpleTriggerFactoryBean

兩種觸發器的示例

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz
.SimpleTriggerFactoryBean">
<!-- see the example of method invoking job above -->
<property name="jobDetail" ref="jobDetail" />
<!-- 10 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="50000" />
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz
.CronTriggerFactoryBean">
<property name="jobDetail" ref="exampleJob" />
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0 0 6 * * ?" />
<!-- 每天早上六點執行-->
</bean>

以上是“Spring任務執行和調度的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德格县| 昭苏县| 文化| 成武县| 册亨县| 旬阳县| 阿合奇县| 司法| 府谷县| 柘城县| 洞头县| 南涧| 昌宁县| 醴陵市| 海林市| 怀来县| 亚东县| 芮城县| 双流县| 乾安县| 龙口市| 武陟县| 施秉县| 灯塔市| 固镇县| 汝城县| 武汉市| 沅江市| 金溪县| 弋阳县| 修水县| 新民市| 班戈县| 道孚县| 普陀区| 深水埗区| 太白县| 民权县| 武安市| 简阳市| 鄂伦春自治旗|