1、线程池
Java中的线程池创建实际都是一个方法。
ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue)
2、示例代码
public class ThreadPoolExecutorSimple {
public static void main(String[] args) {
// 创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE,根据需要创建新线程,但将重用以前构造的线程可用。
Executors.newCachedThreadPool();
new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
// 创建重用固定数量线程的线程池在共享的无边界队列上操作。
Executors.newFixedThreadPool(5);
new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
// 创建使用单个工作线程操作的执行器从一个没有边界的队列中。
Executors.newSingleThreadExecutor();
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
// 创建一个线程池,该线程池可以安排命令在给予延迟,或定期执行。
Executors.newScheduledThreadPool(5);
// new ThreadPoolExecutor(5, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, new DelayedWorkQueue(), Executors.defaultThreadFactory(), new AbortPolicy());
// 创建可调度命令的单线程执行器在给定的延迟之后运行,或定期执行。
Executors.newSingleThreadScheduledExecutor();
// new ThreadPoolExecutor(1, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, new DelayedWorkQueue(), Executors.defaultThreadFactory(), new AbortPolicy());
// 创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要穿一个并行级别的参数,如果不传,则被设定为默认的CPU数量。
Executors.newWorkStealingPool();
new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
// corePoolSize 要保留在池中的线程数,即使它们是空闲的
// maximumPoolSize 池中允许的最大线程数
// keepAliveTime 当线程数大于核心时,这是多余的空闲线程在终止前等待新任务的最长时间
// unit 单位时间的单位
// workQueue 工作队列用于在执行任务之前保存任务的队列
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());
for (int i = 0; i < 10; i++) {
threadPoolExecutor.submit(new ThreadPoolExecutorSimple.TestRunnable(i));
System.out.println("线程池中线程数目:"+threadPoolExecutor.getPoolSize()+",队列中等待执行的任务数目:"+
threadPoolExecutor.getQueue().size()+",已执行玩别的任务数目:"+threadPoolExecutor.getCompletedTaskCount());
}
/**
* 线程池拒绝接受新提交的任务,等待线程池的任务执行完毕后关闭线程池。
* 使用shutdown()关闭线程池,一定要确保任务里不会有永久阻塞的等待的逻辑,否则线程池就关闭不了了。
*/
threadPoolExecutor.shutdown();
/**
* 线程池拒绝接受新提交的任务,立即关闭线程池,线程池中的任务不再执行。
* 使用shutdownNow()关闭线程池,一定要进行异常捕获。
*/
threadPoolExecutor.shutdownNow();
try {
/**
* 调用shutdown()/shutdownNow()方法后线程池并不是立马关闭了,要想等待线程关闭需要调用awaitTermination方法来阻塞等待。
*/
threadPoolExecutor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static class TestRunnable implements Runnable {
private int index;
public TestRunnable(int index) {
this.index = index;
}
public void run() {
Thread currentThread = Thread.currentThread();
System.out.println("线程:" + currentThread.getId() + " 中的任务(" + index + ")开始执行");
synchronized (currentThread) {
try {
Thread.sleep(index * 500);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("线程:" + currentThread.getId() + " 中的任务(" + index + ")执行完成");
}
}
}