Android 线程池的使用

sancaiodm Android源码摘录 2021-09-25 989 0

aosp\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\notification\NotificationInflater.java

可以直接使用范例:

    private static class InflationExecutor implements Executor {
        private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
        // We want at least 2 threads and at most 4 threads in the core pool,
        // preferring to have 1 less than the CPU count to avoid saturating
        // the CPU with background work
        private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
        private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
        private static final int KEEP_ALIVE_SECONDS = 30;
 
        private static final ThreadFactory sThreadFactory = new ThreadFactory() {
            private final AtomicInteger mCount = new AtomicInteger(1);
 
            public Thread newThread(Runnable r) {
                return new Thread(r, "InflaterThread #" + mCount.getAndIncrement());
            }
        };
 
        private final ThreadPoolExecutor mExecutor;
 
        private InflationExecutor() {
            mExecutor = new ThreadPoolExecutor(
                    CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(), sThreadFactory);
            mExecutor.allowCoreThreadTimeOut(true);
        }
 
        @Override
        public void execute(Runnable runnable) {
            mExecutor.execute(runnable);
        }
    }
    
    使用:
    
    new  InflationExecutor().execute(new Runnable(){
         //
         run(){
         //do somethings
         }
       };
    );


方案二:

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;
    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);
    public static final Executor THREAD_POOL_EXECUTOR
        = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
            TimeUnit.SECONDS, sPoolWorkQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
    
    
    THREAD_POOL_EXECUTOR.execute(initialize);
    
     private Runnable initialize = new Runnable() {

        @Override
        public void run() {
           //do somethings
        }
    };



方案三:

aosp/packages/apps/Launcher3/src/com/android/launcher3/util/Executors.java

import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Various different executors used in Launcher
 */
public class Executors {

    // These values are same as that in {@link AsyncTask}.
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;

    /**
     * An {@link ThreadPoolExecutor} to be used with async task with no limit on the queue size.
     */
    public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>());

    /**
     * Returns the executor for running tasks on the main thread.
     */
    public static final LooperExecutor MAIN_EXECUTOR =
            new LooperExecutor(Looper.getMainLooper());

    /**
     * A background executor for using time sensitive actions where user is waiting for response.
     */
    public static final LooperExecutor UI_HELPER_EXECUTOR =
            new LooperExecutor(createAndStartNewForegroundLooper("UiThreadHelper"));

    /**
     * Executor used for running Launcher model related tasks (eg loading icons or updated db)
     */
    public static final LooperExecutor MODEL_EXECUTOR =
            new LooperExecutor(createAndStartNewLooper("launcher-loader"));
            
            
    /**
     * Utility method to get a started handler thread statically
     */
    public static Looper createAndStartNewLooper(String name) {
        return createAndStartNewLooper(name, Process.THREAD_PRIORITY_DEFAULT);
    }

    /**
     * Utility method to get a started handler thread statically with the provided priority
     */
    public static Looper createAndStartNewLooper(String name, int priority) {
        HandlerThread thread = new HandlerThread(name, priority);
        thread.start();
        return thread.getLooper();
    }

    /**
     * Similar to {@link #createAndStartNewLooper(String)}, but starts the thread with
     * foreground priority.
     * Think before using
     */
    public static Looper createAndStartNewForegroundLooper(String name) {
        return createAndStartNewLooper(name, Process.THREAD_PRIORITY_FOREGROUND);
    }
}



LooperExecutor.java的定义如下

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;

import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Extension of {@link AbstractExecutorService} which executed on a provided looper.
 */
public class LooperExecutor extends AbstractExecutorService {

    private final Handler mHandler;

    public LooperExecutor(Looper looper) {
        mHandler = new Handler(looper);
    }

    public Handler getHandler() {
        return mHandler;
    }

    @Override
    public void execute(Runnable runnable) {
        if (getHandler().getLooper() == Looper.myLooper()) {
            runnable.run();
        } else {
            getHandler().post(runnable);
        }
    }

    /**
     * Same as execute, but never runs the action inline.
     */
    public void post(Runnable runnable) {
        getHandler().post(runnable);
    }

    /**
     * Returns the thread for this executor
     */
    public Thread getThread() {
        return getHandler().getLooper().getThread();
    }

    /**
     * Returns the looper for this executor
     */
    public Looper getLooper() {
        return getHandler().getLooper();
    }
    
    /**
     * Not supported and throws an exception when used.
     */
    @Override
    @Deprecated
    public void shutdown() {
        throw new UnsupportedOperationException();
    }

    /**
     * Not supported and throws an exception when used.
     */
    @Override
    @Deprecated
    public List<Runnable> shutdownNow() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isShutdown() {
        return false;
    }

    @Override
    public boolean isTerminated() {
        return false;
    }

    /**
     * Not supported and throws an exception when used.
     */
    @Override
    @Deprecated
    public boolean awaitTermination(long l, TimeUnit timeUnit) {
        throw new UnsupportedOperationException();
    }

    /**
     * Set the priority of a thread, based on Linux priorities.
     * @param priority Linux priority level, from -20 for highest scheduling priority
     *                to 19 for lowest scheduling priority.
     * @see Process#setThreadPriority(int, int)
     */
    public void setThreadPriority(int priority) {
        Process.setThreadPriority(((HandlerThread) getThread()).getThreadId(), priority);
    }
}


使用示例1

            Executors.MAIN_EXECUTOR.execute(() -> {
               //do somethins
            });
            
            
            Executors.UI_HELPER_EXECUTOR.execute(() -> {
                //do somethins
            });
            
            Executors.MODEL_EXECUTOR.execute(() -> {
                //do somethins
            });
                
	    Executors.THREAD_POOL_EXECUTOR.execute(new Runnable() {
		@Override
		public void run() {
		    //do somethins	
		}
	    });
	    
	    Executors.MODEL_EXECUTOR.post(() -> {
               //do somethins
            });
		
		       
            Executors.THREAD_POOL_EXECUTOR.execute(() -> {
            File parent = new File(context.getCacheDir(), SUB_FOLDER);
            File[] files = parent.listFiles((File f, String s) -> s.startsWith(BASE_NAME));
                if (files != null) {
                    for (File file: files) {
                        if (file.lastModified() + FILE_LIFE < System.currentTimeMillis()) {
                            file.delete();
                        }
                    }
                }
             });
             
             
            Executors.THREAD_POOL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                     //do somethins
                }
             });
                
                Executors.MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
                Executors.MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);


评论