一、 相关类
1. GlideExecutor
二、几个重要的线程池
1. 磁盘缓存线程池
//磁盘缓存线程池大小默认是1
private static final int DEFAULT_DISK_CACHE_EXECUTOR_THREADS = 1;
public static GlideExecutor newDiskCacheExecutor() {
return newDiskCacheExecutor(
DEFAULT_DISK_CACHE_EXECUTOR_THREADS,
DEFAULT_DISK_CACHE_EXECUTOR_NAME,
UncaughtThrowableStrategy.DEFAULT);
}
public static GlideExecutor newDiskCacheExecutor(
int threadCount, String name, UncaughtThrowableStrategy uncaughtThrowableStrategy) {
return new GlideExecutor(
new ThreadPoolExecutor(
threadCount /* corePoolSize */,
threadCount /* maximumPoolSize */,
0 /* keepAliveTime */,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(name, uncaughtThrowableStrategy, true)));
}
2. 核心处理线程池
//线程池大小默认为4个
private static final int MAXIMUM_AUTOMATIC_THREAD_COUNT = 4;
MAXIMUM_AUTOMATIC_THREAD_COUNT
public static GlideExecutor newSourceExecutor() {
return newSourceExecutor(
calculateBestThreadCount(),
DEFAULT_SOURCE_EXECUTOR_NAME,
UncaughtThrowableStrategy.DEFAULT);
}
public static GlideExecutor newSourceExecutor(
int threadCount, String name, UncaughtThrowableStrategy uncaughtThrowableStrategy) {
return new GlideExecutor(
new ThreadPoolExecutor(
threadCount /* corePoolSize */,
threadCount /* maximumPoolSize */,
0 /* keepAliveTime */,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(name, uncaughtThrowableStrategy, false)));
}
//计算最合适的线程池数量
public static int calculateBestThreadCount() {
if (bestThreadCount == 0) {
//线程池大小最大为4个,4和cpu数量取小值
bestThreadCount =
Math.min(MAXIMUM_AUTOMATIC_THREAD_COUNT, RuntimeCompat.availableProcessors());
}
return bestThreadCount;
}
//获取可用cpu数量
static int availableProcessors() {
int cpus = Runtime.getRuntime().availableProcessors();
if (Build.VERSION.SDK_INT < 17) {
//api-17以前的兼容处理
cpus = Math.max(getCoreCountPre17(), cpus);
}
return cpus;
}
private static int getCoreCountPre17() {
// We override the current ThreadPolicy to allow disk reads.
// This shouldn't actually do disk-IO and accesses a device file.
// See: https://github.com/bumptech/glide/issues/1170
File[] cpus = null;
ThreadPolicy originalPolicy = StrictMode.allowThreadDiskReads();
try {
File cpuInfo = new File(CPU_LOCATION);
final Pattern cpuNamePattern = Pattern.compile(CPU_NAME_REGEX);
cpus = cpuInfo.listFiles(new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
return cpuNamePattern.matcher(s).matches();
}
});
} catch (Throwable t) {
if (Log.isLoggable(TAG, Log.ERROR)) {
Log.e(TAG, "Failed to calculate accurate cpu count", t);
}
} finally {
StrictMode.setThreadPolicy(originalPolicy);
}
return Math.max(1, cpus != null ? cpus.length : 0);
}
3. 动画线程池
public static GlideExecutor newAnimationExecutor() {
int bestThreadCount = calculateBestThreadCount();
// We don't want to add a ton of threads running animations in parallel with our source and
// disk cache executors. Doing so adds unnecessary CPU load and can also dramatically increase
// our maximum memory usage. Typically one thread is sufficient here, but for higher end devices
// with more cores, two threads can provide better performance if lots of GIFs are showing at
// once.
//如果cpu数量大于等于4个,则此线程池大小默认为2个,否则否则为1个
int maximumPoolSize = bestThreadCount >= 4 ? 2 : 1;
return newAnimationExecutor(maximumPoolSize, UncaughtThrowableStrategy.DEFAULT);
}
public static GlideExecutor newAnimationExecutor(
int threadCount, UncaughtThrowableStrategy uncaughtThrowableStrategy) {
return new GlideExecutor(
new ThreadPoolExecutor(
0 /* corePoolSize */,
threadCount,
KEEP_ALIVE_TIME_MS,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(
ANIMATION_EXECUTOR_NAME,
uncaughtThrowableStrategy,
true)));
}
3. Runtime.getRuntime().availableProcessors()
a. 然而,更大的问题在于Runtime.getRuntime().availableProcessors()也并非都能返回你所期望的数值。比如说,在我的双核1-2-1机器上,它返回的是2,这是对的。不过在我的1-4-2机器 上,也就是一个CPU插槽,4核,每个核2个超线程,这样的话会返回8。不过我其实只有4个核,如果代码的瓶颈是在CPU这块的话,我会有7个线程在同时 竞争CPU周期,而不是更合理的4个线程。如果我的瓶颈是在内存这的话,那这个测试我可以获得7倍的性能提升。
b. 不过这还没完!Java Champions上的一个哥们发现了一种情况,他有一台16-4-2的机器 (也就是16个CPU插槽,每个CPU4个核,每核两个超线程,返回的值居然是16!从我的i7 Macbook pro上的结果来看,我觉得应该返回的是1642=128。在这台机器上运行Java 8的话,它只会将通用的FJ池的并发数设置成15。正如 Brian Goetz所指出的,“虚拟机其实不清楚什么是处理器,它只是去请求操作系统返回一个值。同样的,操作系统也不知道怎么回事,它是去问的硬件设备。硬件会告诉它一个值,通常来说是硬件线程数。操作系统相信硬件说的,而虚拟机又相信操作系统说的。”