多线程环境下需要定期执行周期任务,Timer不建议使用了。

newSingleThreadScheduledExecutor:只包含一个线程,只需要单个线程执行周期任务,保证顺序的执行各个任务

newScheduledThreadPool 可以包含多个线程的,线程执行周期任务,适度控制后台线程数量的时候

方法说明:

schedule:只执行一次,任务还可以延时执行

scheduleAtFixedRate:提交固定时间间隔的任务,这个是一个任务的开始到另外一个任务的开始

scheduleWithFixedDelay:提交固定延时间隔执行的任务,这个是从一个任务的结束到另外一个任务的开始。

两者的区别:

java并发编程(十九)- 线程池(ScheduledThreadPoolExecutor )详细使用_抛出异常

 

scheduleAtFixedRate任务超时:

规定60s执行一次,有任务执行了80S,下个任务马上开始执行

第一个任务 时长 80s,第二个任务20s,第三个任务 50s

第一个任务第0秒开始,第80S结束;

第二个任务第80s开始,在第100秒结束;

第三个任务第120s秒开始,170秒结束

第四个任务从180s开始

参加代码:ScheduleWorkerTime类,执行效果如图:

java并发编程(十九)- 线程池(ScheduledThreadPoolExecutor )详细使用_代码实现_02

 

在提交给ScheduledThreadPoolExecutor的任务要住catch异常,不然会导致进程一直存在。

 

代码实现:

package com.caojiulu;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
*@author caojiuliu
*
*类说明:定时任务的工作类
*/
public class ScheduleWorker implements Runnable{
public final static int Normal = 0;//普通任务类型
public final static int HasException = -1;//会抛出异常的任务类型
public final static int ProcessException = 1;//抛出异常但会捕捉的任务类型

public static SimpleDateFormat formater = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");

private int taskType;
public ScheduleWorker(int taskType) {
this.taskType = taskType;
}

@Override
public void run() {
if(taskType==HasException) {
System.out.println(formater.format(new Date())+" Exception made...");
throw new RuntimeException("HasException Happen");
}else if(taskType==ProcessException) {
try {
System.out.println(formater.format(new Date())
+" Exception made,but catch");
throw new RuntimeException("HasException Happen");
}catch(Exception e) {
System.out.println(" Exception be catched");
}
}else {
System.out.println(" Normal ...."+formater.format(new Date()));
}
}
}

测试类:

package com.caojiulu;

import java.util.Date;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.caojiulu.SleepTools;

/**
*@author caojiulu
*
*类说明:演示ScheduledThreadPoolExecutor的用法
*/
public class ScheduledCase {
public static void main(String[] args) {

ScheduledThreadPoolExecutor schedule
= new ScheduledThreadPoolExecutor(1);

schedule.scheduleAtFixedRate(new ScheduleWorker(ScheduleWorker.HasException),
1000, 3000, TimeUnit.MILLISECONDS);
schedule.scheduleAtFixedRate(new ScheduleWorker(ScheduleWorker.Normal),
1000, 3000, TimeUnit.MILLISECONDS);

}
}

当然创建的方式还有:

ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);这是大家比较常用的方式。