线程池
我们可以查看线程池的源码,然后查看到最顶端,Executor是一个接口,需要实现。
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
点下去看又有ExecutorService继承Executor,可是ExecutorService依旧是接口。
public interface ExecutorService extends Executor
再继续点下去(IDEA: Ctrl + Alt + B):
public abstract class AbstractExecutorService implements ExecutorService
然后就发现有两个类继承了这个虚拟类:
ThreadPoolExecutor
public class ThreadPoolExecutor extends AbstractExecutorService
ScheduledThreadPoolExecutor
public class ScheduledThreadPoolExecutor
extends ThreadPoolExecutor
implements ScheduledExecutorService
这就是线程池不允许使用 Executor去创建的原因,可以通过 ThreadPoolExecutor 的方式,这样的处理方式也能更加明确线程池的运行规则,规避资源耗尽的风险。
通过ThreadPoolExecutor类创建,最原始的创建线程池的方式,它包含了 7 个参数可供设置,可以查看源码:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 线程存活时间
unit 时间单位
workQueue 等待队列
这是其中的一个构造函数,如果有其他的要求可以看其他的构造函数。
另一种方式是使用Executors,这是一个类:
public class Executors
可以看下面的函数,有很多创建各种各样类型线程池的函数,返回值都是ExecutorService:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Executors 返回的线程池对象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
自己写了个例子,使用第一种方式:
public class ThreadPoolTest {
public static void main(String[] args) {
List<String> types = new ArrayList<>();
for(int i = 0; i < 18; i++) {
types.add("Test" + i);
}
ExecutorService executorService = new ThreadPoolExecutor(4, 6, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(12));
for(String type : types) {
ThreadAssembler threadAssembler = new ThreadAssembler();
threadAssembler.setType(type);
executorService.execute(threadAssembler);
}
}
}
这里List的长度是18,所以在创建线程池的时候,maximumPoolSize + workQueue.size() >= 18,不然会报错(毕竟等待的线程塞不进你申请的线程池)。
public class AllAssembler {
protected String type;
public void setType(String type) {
this.type = type;
}
}
public class ThreadAssembler extends AllAssembler implements Runnable {
@Override
public void run() {
try {
System.out.println("Get Thread Assember " + type);
} catch (Exception e) {
System.out.println("Error");
}
最后的结果:


浙公网安备 33010602011771号