java并发编程(十九)- 线程池(ScheduledThreadPoolExecutor )详细使用
原创
©著作权归作者所有:来自51CTO博客作者日薪灬越亿的原创作品,请联系作者获取转载授权,否则将追究法律责任
多线程环境下需要定期执行周期任务,Timer不建议使用了。
newSingleThreadScheduledExecutor:只包含一个线程,只需要单个线程执行周期任务,保证顺序的执行各个任务
newScheduledThreadPool 可以包含多个线程的,线程执行周期任务,适度控制后台线程数量的时候
方法说明:
schedule:只执行一次,任务还可以延时执行
scheduleAtFixedRate:提交固定时间间隔的任务,这个是一个任务的开始到另外一个任务的开始
scheduleWithFixedDelay:提交固定延时间隔执行的任务,这个是从一个任务的结束到另外一个任务的开始。
两者的区别:
scheduleAtFixedRate任务超时:
规定60s执行一次,有任务执行了80S,下个任务马上开始执行
第一个任务 时长 80s,第二个任务20s,第三个任务 50s
第一个任务第0秒开始,第80S结束;
第二个任务第80s开始,在第100秒结束;
第三个任务第120s秒开始,170秒结束
第四个任务从180s开始
参加代码:ScheduleWorkerTime类,执行效果如图:
在提交给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);这是大家比较常用的方式。