java并发编程(十九)- 线程池(ScheduledThreadPoolExecutor )详细使用
多线程环境下需要定期执行周期任务,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);这是大家比较常用的方式。
上一篇:
多线程四大经典案例