快捷搜索: 长连接 前端 源码 pan

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);这是大家比较常用的方式。

经验分享 程序员 微信小程序 职场和发展