ThreadPool线程池
线程池
- 3大方法,7大参数,4大拒绝策略
- 降低资源消耗
- 提高响应速度
- 方便管理
- 线程复用,控制最大并发数,管理线程
- 最大线程定义
- CPU密集型:几核cpu就设置为几,通过代码去获取Runtime().getRuntime().availableProcessors()
- IO密集型:判断程序中十分耗费IO的线程
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Demo1 {
public static void main(String[] args) {
// 单个线程
// ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 可伸缩的
// ExecutorService threadPool = Executors.newCachedThreadPool();
// 固定大小
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// CPU核心数
System.out.println(Runtime.getRuntime().availableProcessors() + "核");
try {
for (int i = 0; i < 10; i++) {
// 使用线程池创建线程
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
- Executor源码
public interface Executor {
void execute(Runnable command);
}
- ExecutorService源码
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
- Executors部分函数全是调用了ThreadPoolExecutors的构造函数
public static ExecutorService newSingleThreadExecutor () {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool ( int nThreads){
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool () {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- ThreadPoolExecutor主要构造函数
public ThreadPoolExecutor(int corePoolSize, // 核心线程大小
int maximumPoolSize, // 最大大小
long keepAliveTime, // 超时了没人调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler) { // 拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
-
拒绝策略(阻塞队列满了后触发拒绝策略)
- AbortPolicy():抛出异常
- CallerRunsPolicy():把任务队列中的任务放在调用者线程当中运行
- DiscardPolicy() :丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交
- DiscardOldestPolicy():尝试和最早的线程竞争,不会抛出异常
-
自定义线程池
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
class Demo1 {
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, // 核心线程大小
5, // 最大大小(阻塞队列满了后会启用新线程)
3, // 超时时间(超时释放的是非核心的线程)
TimeUnit.SECONDS, // 超时时间单位
new LinkedBlockingQueue<>(3), // 阻塞队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy()); // 阻塞队列满了后的拒绝策略
try {
// 最大承载 = 队列 + max
for (int i = 0; i < 10; i++) {
// 使用线程池创建线程
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭线程池
threadPool.shutdown();
}
}
}
- 阻塞队列
- new LinkedBlockingQueue<>(3):设置固定的容量,此例中:i < 5时,阻塞队列刚刚满,5个任务使用两个核心线程;i < 6时,多了一个线程,6>队列+core,此时会新开辟一个线程(总线程数不大于5),6个任务使用两个核心线程和一个新开辟的线程
- new LinkedBlockingQueue<>():无界阻塞队列。默认容量为Integer.MAX_VALUE,核心线程都被使用后,新来的线程全都放在阻塞队列中,此时相当于设置的maximumPoolSize无效,并发数固定为corePoolSize
- new SynchronousQueue<>():创建的线程数大于maximumPoolSize时,直接执行拒绝策略
- new ArrayBlockingQueue<>(3):有界阻塞队列。类似new LinkedBlockingQueue<>(3)
- new PriorityBlockingQueue<>():优先级阻塞队列