创建线程池
使用线程池处理多线程可以节约资源,以更小的开销做更多的事,从而提高性能。自JDK5之后,Java推出了一个并发包,java.util.concurrent,接下来咱们看看在Java并发包下如何创建线程池。
// 创建可重用-固定线程数目的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
// 创建可重用-线程池的大小会根据执行任务数动态分配的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 创建使用单个worker线程的Executor
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
// 创建可安排给定延时后运行任务-定期执行任务的线程池
ExecutorService scheduleThreadPool = Executors
.newScheduledThreadPool(2);
用法以及区别
for (int i = 0; i < 5; i++) {
final int taskId = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 5; i++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务" + taskId + "第" + i + "次执行");
}
}
});
}
fixedThreadPool 输出结果:
任务0第1次执行
任务1第1次执行
任务0第2次执行
任务1第2次执行
任务0第3次执行
任务1第3次执行
任务0第4次执行
任务1第4次执行
任务2第1次执行
任务3第1次执行
任务3第2次执行
任务2第2次执行
任务3第3次执行
任务2第3次执行
任务3第4次执行
任务2第4次执行
任务4第1次执行
任务4第2次执行
任务4第3次执行
任务4第4次执行
将fixedThreadPool 改成cachedThreadPool 输出结果如下:
任务3第1次执行
任务1第1次执行
任务2第1次执行
任务4第1次执行
任务0第1次执行
任务4第2次执行
任务0第2次执行
任务1第2次执行
任务2第2次执行
任务3第2次执行
任务3第3次执行
任务0第3次执行
任务2第3次执行
任务1第3次执行
任务4第3次执行
任务2第4次执行
任务1第4次执行
任务4第4次执行
任务3第4次执行
任务0第4次执行
将cachedThreadPool 改成singleThreadPool输出结果如下:
任务0第1次执行
任务0第2次执行
任务0第3次执行
任务0第4次执行
任务1第1次执行
任务1第2次执行
任务1第3次执行
任务1第4次执行
任务2第1次执行
任务2第2次执行
任务2第3次执行
任务2第4次执行
任务3第1次执行
任务3第2次执行
任务3第3次执行
任务3第4次执行
任务4第1次执行
任务4第2次执行
任务4第3次执行
任务4第4次执行
ScheduledThreadPool可以定时的或延时的执行任务,示例代码如下:
package org.iti.thread;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadDemo_5 {
private static long startAt;
public static void main(String[] args) {
ScheduledExecutorService newScheduledThreadPool = Executors
.newScheduledThreadPool(2);
TimerTask task1 = new TimerTask() {
@Override
public void run() {
System.out.println(String.format("任务1开始于%s毫秒后",
(System.currentTimeMillis() - startAt)));
try {
Thread.sleep(4000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
TimerTask task2 = new TimerTask() {
@Override
public void run() {
System.out.println(String.format("任务2开始于%s毫秒后",
(System.currentTimeMillis() - startAt)));
}
};
startAt = System.currentTimeMillis();
newScheduledThreadPool.schedule(task1, 1000, TimeUnit.MILLISECONDS);
newScheduledThreadPool.schedule(task2, 3000, TimeUnit.MILLISECONDS);
}
}