系列文章
OkHttp学习(一) OSI七层模型和TCP四层模型
OkHttp学习(二) 3.10.0版本的简单使用及其流程梳理
OkHttp学习(三) 3.10.0版本源码阅读之线程池
OkHttp学习(四) 3.10.0版本源码阅读之构建者设计模式
OkHttp学习(五) 3.10.0版本源码阅读之责任链设计模式
OkHttp学习(六) 3.10.0版本源码中的拦截器
OkHttp学习(七) 手写OkHttp之框架搭建
OkHttp学习(八) 手写OkHttp之网络请求实现
OkHttp学习(九) OkHttp的连接池手写实现
Java中线程池的体系结构
ThreadPoolExecutor的简单使用
创建线程池对象
ExecutorService executorService =
new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
使用线程池对象执行多个任务
for (int i = 0; i < 20; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("当前线程,执行耗时任务,线程是:" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
这样创建的Executor的执行结果为
重复使用已经创建的Thread。达到了线程池的作用。
ThreadPoolExecutor构造函数的参数分析
参数一:corePoolSize 核心线程数
参数二:maximumPoolSize 线程池非核心线程数 线程池规定大小
参数三/四:时间数值keepAliveTime, 单位:时分秒 60s
正在执行的任务Runnable20 > corePoolSize --> 参数三/参数四 才会起作用
作用:Runnable1执行完毕后 闲置60s,如果过了闲置60s,会回收掉Runnable1任务,,如果在闲置时间60s 复用此线程Runnable1
参数五:workQueue队列 :会把超出的任务加入到队列中 缓存起来
参数六:创建Thread的工厂类对象,指定创建Thread的方法。
使用缓存方案的线程池
ExecutorService executorService =
new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread();
thread.setName("MyOkHttp Dispatcher");
thread.setDaemon(false); // 不是守护线程
return thread;
}
});
上述代码中将核心线程数设置为0,线程池规定大小是int的最大值,闲置时间设置为60s,这样设置出来的执行结果是
只是用一个线程, 这就是缓存方案的线程池。 因为这一个线程可以满足任务的需要,不需要再创建其它线程了。我们设置的线程池容量是int的最大值,理论上是可以创建那么多线程的,但是实际中会按照需要创建线程,如果线程闲置超过60s才会被回收,没有超过60s,会接着执行下个任务。
OkHttp中的线程池
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
OkHttp中同样也是这么创建线程池的, 核心线程是0,线程池容量为int的最大值,闲置时间设置为60s。这么做也提高了OkHttp的性能。
总结
OKHTTP线程池采用的是缓存方案 + 定义线程工程(设置线程名,设置不是守护线程)