一、Java通过Executors提供四种线程池,分别为:
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,表示同一时刻只能有这么大的并发数
newScheduledThreadPool 创建一个定时线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
二、ScheduledThreadPoolExecutor用于定时任务,这里的定时意义在于:
指定延时后执行任务。
周期性重复执行任务。
接着分析ScheduledThreadPoolExecutor源码,从类声明开始
类声明
public class ScheduledThreadPoolExecutor
extends ThreadPoolExecutor
implements ScheduledExecutorService {
//……
}
ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,实现了ScheduledExecutorService。在线程池的基础上,实现了可调度的线程池功能。上一篇文章已经详细介绍了ThreadPoolExecutor,这里我们先看下ScheduledExecutorService的源码:
ScheduledExecutorService
//可调度的执行者服务接口
public interface ScheduledExecutorService extends ExecutorService {
//指定时延后调度执行任务
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
//指定时延后调度执行任务
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
//指定时延后开始执行任务,以后每隔period的时长再次执行该任务
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
//指定时延后开始执行任务,以后任务执行完成后等待delay时长,再次执行任务
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
}
ScheduledExecutorService实现了ExecutorService,并增加若干定时相关的接口。其中schedule方法用于单次调度执行任务。这里主要理解下后面两个方法。
• scheduleAtFixedRate:该方法在initialDelay时长后第一次执行任务,以后每隔period时长,再次执行任务。注意,period是从任务开始执行算起的。开始执行任务后,定时器每隔period时长检查该任务是否完成,如果完成则再次启动任务,否则等该任务结束后才再次启动任务,看下图示例。
![](https://img.haomeiwen.com/i8181203/88bf41e2e65e88dd.png)
• scheduleWithFixDelay:该方法在initialDelay时长后第一次执行任务,以后每当任务执行完成后,等待delay时长,再次执行任务,看下图示例。
![](https://img.haomeiwen.com/i8181203/3d0a2ad140943575.png)
碰到过问题:ScheduledExecutorService 如何结束掉一条子线程任务
Java 程序员都知道我们可以用 ScheduledExecutorService 按照一定的间隔或频率执行任务,但这个任务一旦开始,就只能到 ThreadPool shutdown 了才能结束。如何按照一定条件,在不终止整个线程池的情况下结束任务,可以通过抛出异常去结束掉。
private Map<String, Integer> map = new HashMap<String, Integer>();
public void sendMessage(final String message) throws IOException{
scheduledService.scheduleAtFixedRate(new Runnable() {
public void run() {
Integer integer = 0;
if (map.containsKey(message)) {
integer = map.get(message);
integer ++;
map.put(message, integer);
} else {
map.put(message, integer);
}
try {
System.out.println("ThreadSendSocket:" + integer + "\t" + message + "\t" + new Date());
} catch (IOException e) {
e.printStackTrace();
}
if(map.get(message) == 10) {
// scheduledService.shutdownNow(); /停止线程池的操作
System.out.println("kill Thread" + message);
throw new RuntimeException("kill Thread" + message);
}
}
}, 0, 2000, TimeUnit.MILLISECONDS);
}
ScheduledThreadPoolExecutor参考:https://blog.csdn.net/luanmousheng/article/details/77816412
网友评论