- 常用多线程
ExecutorService executor01 = Executors.newCachedThreadPool();
- 使用方式及参数配置详解
/**
* Creates a thread pool that creates new threads as needed, but
* will reuse previously constructed threads when they are
* available. These pools will typically improve the performance
* of programs that execute many short-lived asynchronous tasks.
* Calls to {@code execute} will reuse previously constructed
* threads if available. If no existing thread is available, a new
* thread will be created and added to the pool. Threads that have
* not been used for sixty seconds are terminated and removed from
* the cache. Thus, a pool that remains idle for long enough will
* not consume any resources. Note that pools with similar
* properties but different details (for example, timeout parameters)
* may be created using {@link ThreadPoolExecutor} constructors.
*
* @return the newly created thread pool
*/
/**
* 创建一个线程池,根据需要创建新线程,但是
* 将重用之前构造的线程
* 可用。这些池通常会提高性能执行许多短期异步任务的程序。
* 调用{@code execute}将重用先前构造的代码
* 线程(如果可用)。如果没有现有线程可用,则创建一个新的线程
* 线程将被创建并添加到池中。具有
* 未使用60秒被终止并从
* 缓存。因此,一个保持空闲足够长的池将会
* 不消耗任何资源。请注意具有相似的池
* 属性,但不同的细节(例如超时参数)
* 可以使用{@link ThreadPoolExecutor}构造函数创建。
* @返回新建的线程池
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- 特点
1. 不会创建核心线程;
2. 把任务放到SynchronousQueue,offer方法不会阻塞,如果当前没有线程来拿这个任务,就会失败。
3. 会自动调节,如果某个线程一段时间不用。就会回收。更加的节省资源。
4. 它是一个可以无限扩大的线程池;它比较适合处理执行时间比较小的任务;corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。
5. 4失败后创建空闲线程执行任务,因为空闲线程可以是Integer.MAX_VALUE,所以会成功。
- 注意
1. 从工作特点可以看出SynchronousQueue不适合频繁提交任务,并且任务不适合执行时间过长
2. 高并发下会创建大量空闲线程导致OOM;
- 使用方式:
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
int temp = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "," + temp);
}
});
}
}
pool-1-thread-1,0
pool-1-thread-2,1
pool-1-thread-3,2
pool-1-thread-4,3
pool-1-thread-5,4
pool-1-thread-6,5
pool-1-thread-7,6
pool-1-thread-8,7
pool-1-thread-9,8
pool-1-thread-10,9
可以看到,循环多少次,创建了多少线程
- 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程