1. 程式人生 > >glide之執行緒池

glide之執行緒池

## 相關類 1. GlideExecutor

## 磁碟快取執行緒池 ``` //磁碟快取執行緒池大小預設是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)));   } ```

## 核心處理執行緒池 ``` //執行緒池大小預設為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);   } ```

## 動畫執行緒池 ``` 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)));   } ```

## Runtime.getRuntime().availableProcessors() 1. 然而,更大的問題在於Runtime.getRuntime().availableProcessors()也並非都能返回你所期望的數值。比如說,在我的雙核1-2-1機器上,它返回的是2,這是對的。不過在我的1-4-2機器 上,也就是一個CPU插槽,4核,每個核2個超執行緒,這樣的話會返回8。不過我其實只有4個核,如果程式碼的瓶頸是在CPU這塊的話,我會有7個執行緒在同時 競爭CPU週期,而不是更合理的4個執行緒。如果我的瓶頸是在記憶體這的話,那這個測試我可以獲得7倍的效能提升。 2. 不過這還沒完!Java Champions上的一個哥們發現了一種情況,他有一臺16-4-2的機器 (也就是16個CPU插槽,每個CPU4個核,每核兩個超執行緒,返回的值居然是16!從我的i7 Macbook pro上的結果來看,我覺得應該返回的是1642=128。在這臺機器上執行Java 8的話,它只會將通用的FJ池的併發數設定成15。正如 Brian Goetz所指出的,“虛擬機器其實不清楚什麼是處理器,它只是去請求作業系統返回一個值。同樣的,作業系統也不知道怎麼回事,它是去問的硬體裝置。硬體會告訴它一個值,通常來說是硬體執行緒數。作業系統相信硬體說的,而虛擬機器又相信作業系統說的。”