周期性线程池newScheduledThreadPool详解
线程池支持定时以及周期性执行任务,创建一个corePoolSize为传入参数,最大线程数为整形的最大数的线程池public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSi...
线程池支持定时以及周期性执行任务,创建一个corePoolSize为传入参数,最大线程数为整形的最大数的线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
ScheduledThreadPoolExecutor类的构造:
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());
}
此线程池keepAliveTime参数为0,缓存对列为DelayedWorkQueue。
jdk1.5之前的版本中更多的是借助Timer类来实现,Timer和ScheduledThreadPoolExecutor的区别:
a.Timer单线程运行,一旦任务执行缓慢,下一个任务就会推迟,而如果使用了ScheduledThreadPoolExecutor线程数可以自行控制
b.当Timer中的一个任务抛出异常时,会导致其他所有任务不在执行
c.ScheduledThreadPoolExecutor可执行异步的任务,从而得到执行结果
ScheduledExecutorService接口继承了ExecutorService,在ExecutorService的基础上新增了以下几个方法:
①schedule方法:
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
command:执行的任务 Callable或Runnable接口实现类
delay:延时执行任务的时间
unit:延迟时间单位
示例:
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
ScheduledFuture<String> scheduledFuture = executorService.schedule(new Callable<String>() {
public String call() throws Exception {
return "call";
}
}, 10, TimeUnit.SECONDS);
System.out.println(scheduledFuture.get());
executorService.shutdown();
延迟10秒后,返回call字符串并输出。
执行任务案例:
package com.thread.testExtendsThread.fourPackage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.*;
/**
* @author liuchj
* @version 1.0
* @className ScheduleThreadTest
* @description //TODO
* @date 2019/5/30
**/
public class ScheduleThreadTest {
/**
* 线程安全的队列
*/
static Queue<String> queue = new ConcurrentLinkedQueue<String>();
static {
//入队列
for (int i = 0; i < 9; i++) {
queue.add("task-" + i);
}
}
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
for (int i = 0; i < queue.size(); i++) {
ScheduledFuture<String> scheduledFuture = executorService.schedule(new Callable<String>() {
@Override
public String call() throws Exception {
String value = ThreadPoolTask.queue.poll();
if (value != "" && null != value) {
System.out.println("时间:" + sdf.format(new Date())+"线程" + Thread.currentThread().getName() + " 执行了task: " + value);
}
return "call";
}
}, 3, TimeUnit.SECONDS);
System.out.println(scheduledFuture.get());
}
executorService.shutdown();
}
}
执行结果:
时间:2019-05-30 03:53:11线程pool-1-thread-1 执行了task: task-0
call
时间:2019-05-30 03:53:14线程pool-1-thread-1 执行了task: task-1
call
时间:2019-05-30 03:53:17线程pool-1-thread-1 执行了task: task-2
call
时间:2019-05-30 03:53:20线程pool-1-thread-1 执行了task: task-3
call
时间:2019-05-30 03:53:23线程pool-1-thread-1 执行了task: task-4
call
时间:2019-05-30 03:53:26线程pool-1-thread-1 执行了task: task-5
call
时间:2019-05-30 03:53:29线程pool-1-thread-1 执行了task: task-6
call
时间:2019-05-30 03:53:32线程pool-1-thread-1 执行了task: task-7
call
Disconnected from the target VM, address: '127.0.0.1:59247', transport: 'socket'
时间:2019-05-30 03:53:35线程pool-1-thread-1 执行了task: task-8
call
②scheduleAtFixedRate方法:
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
command:执行的任务 Callable或Runnable接口实现类
initialDelay:第一次执行任务延迟时间
period:连续执行任务之间的周期,从上一个任务开始执行时计算延迟多少开始执行下一个任务,但是还会等上一个任务结束之后。
unit:initialDelay和period时间单位
示例: 注意看输出结果
final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("时间:" + sf.format(new Date()) );
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2, 3, TimeUnit.SECONDS);
输出结果:
时间:2014-04-01 23:44:48
时间:2014-04-01 23:44:53
时间:2014-04-01 23:44:58
时间:2014-04-01 23:45:03
执行任务案例:
public class ScheduledThreadTest {
/**
* 线程安全的队列
*/
static Queue<String> queue = new ConcurrentLinkedQueue<String>();
static {
//入队列
for (int i = 0; i < 9; i++) {
queue.add("task-" + i);
}
}
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("时间:" + sdf.format(new Date()) );
for (int i = 0; i < queue.size(); i++) {
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
String value = ThreadPoolTask.queue.poll();
if (value != "" && null != value) {
System.out.println("时间:" + sdf.format(new Date())+" 线程" + Thread.currentThread().getName() + " 执行了task: " + value);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2, 6, TimeUnit.SECONDS);
}
//不注释这行会打印出问题,应该是先执行关闭线程操作了
// executor.shutdown();
}
}
执行结果:
时间:2019-05-30 03:33:19
时间:2019-05-30 03:33:21 线程pool-1-thread-2 执行了task: task-0
时间:2019-05-30 03:33:21 线程pool-1-thread-1 执行了task: task-1
时间:2019-05-30 03:33:26 线程pool-1-thread-2 执行了task: task-2
时间:2019-05-30 03:33:26 线程pool-1-thread-1 执行了task: task-3
时间:2019-05-30 03:33:31 线程pool-1-thread-2 执行了task: task-4
时间:2019-05-30 03:33:31 线程pool-1-thread-1 执行了task: task-5
时间:2019-05-30 03:33:36 线程pool-1-thread-2 执行了task: task-6
时间:2019-05-30 03:33:36 线程pool-1-thread-1 执行了task: task-7
时间:2019-05-30 03:33:40 线程pool-1-thread-2 执行了task: task-8
③scheduleWithFixedDelay方法:
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
command:执行的任务 Callable或Runnable接口实现类
initialDelay:第一次执行任务延迟时间
period:连续执行任务之间的周期,从上一个任务全部执行完成时计算延迟多少开始执行下一个任务
unit:initialDelay和period时间单位
final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleWithFixedDelay(new Runnable() {
public void run() {
System.out.println("时间:" + sf.format(new Date()) );
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2, 3, TimeUnit.SECONDS);
输出结果:
时间:2014-04-01 23:47:38
时间:2014-04-01 23:47:46
时间:2014-04-01 23:47:54
执行任务案例:
package com.thread.testExtendsThread.fourPackage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.*;
/**
* @author liuchj
* @version 1.0
* @className ScheduledThreadTest
* @description //TODO
* @date 2019/5/30
**/
public class ScheduledThreadTest {
/**
* 线程安全的队列
*/
static Queue<String> queue = new ConcurrentLinkedQueue<String>();
static {
//入队列
for (int i = 0; i < 9; i++) {
queue.add("task-" + i);
}
}
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("时间:" + sdf.format(new Date()) );
for (int i = 0; i < queue.size(); i++) {
executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
String value = ThreadPoolTask.queue.poll();
if (value != "" && null != value) {
System.out.println("时间:" + sdf.format(new Date())+" 线程" + Thread.currentThread().getName() + " 执行了task: " + value);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2, 6, TimeUnit.SECONDS);
}
//这行代码不注释掉,任务都不能执行了,估计先执行此处关闭线程
// executor.shutdown();
}
}
执行结果:
时间:2019-05-30 03:54:45
时间:2019-05-30 03:54:47 线程pool-1-thread-2 执行了task: task-1
时间:2019-05-30 03:54:47 线程pool-1-thread-1 执行了task: task-0
时间:2019-05-30 03:54:52 线程pool-1-thread-1 执行了task: task-2
时间:2019-05-30 03:54:52 线程pool-1-thread-2 执行了task: task-3
时间:2019-05-30 03:54:57 线程pool-1-thread-2 执行了task: task-4
时间:2019-05-30 03:54:57 线程pool-1-thread-1 执行了task: task-5
时间:2019-05-30 03:55:02 线程pool-1-thread-1 执行了task: task-6
时间:2019-05-30 03:55:02 线程pool-1-thread-2 执行了task: task-7
时间:2019-05-30 03:55:07 线程pool-1-thread-1 执行了task: task-8
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)