Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0203aa6 authored by Hans Boehm's avatar Hans Boehm Committed by android-build-merger
Browse files

Merge "Adjust AsyncTask.THREAD_POOL_EXECUTOR config"

am: 2b56c4cf

Change-Id: I0a8554c58710b162df57cbf2ca8dcb7591666ef9
parents 725bf8e5 2b56c4cf
Loading
Loading
Loading
Loading
+40 −12
Original line number Original line Diff line number Diff line
@@ -21,13 +21,14 @@ import android.annotation.Nullable;
import android.annotation.WorkerThread;
import android.annotation.WorkerThread;


import java.util.ArrayDeque;
import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
@@ -190,13 +191,19 @@ import java.util.concurrent.atomic.AtomicInteger;
public abstract class AsyncTask<Params, Progress, Result> {
public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";
    private static final String LOG_TAG = "AsyncTask";


    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // We keep only a single pool thread around all the time.
    // We want at least 2 threads and at most 4 threads in the core pool,
    // We let the pool grow to a fairly large number of threads if necessary,
    // preferring to have 1 less than the CPU count to avoid saturating
    // but let them time out quickly. In the unlikely case that we run out of threads,
    // the CPU with background work
    // we fall back to a simple unbounded-queue executor.
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    // This combination ensures that:
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    // 1. We normally keep few threads (1) around.
    private static final int KEEP_ALIVE_SECONDS = 30;
    // 2. We queue only after launching a significantly larger, but still bounded, set of threads.
    // 3. We keep the total number of threads bounded, but still allow an unbounded set
    //    of tasks to be queued.
    private static final int CORE_POOL_SIZE = 1;
    private static final int MAXIMUM_POOL_SIZE = 20;
    private static final int BACKUP_POOL_SIZE = 5;
    private static final int KEEP_ALIVE_SECONDS = 3;


    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);
        private final AtomicInteger mCount = new AtomicInteger(1);
@@ -206,8 +213,29 @@ public abstract class AsyncTask<Params, Progress, Result> {
        }
        }
    };
    };


    private static final BlockingQueue<Runnable> sPoolWorkQueue =
    // Used only for rejected executions.
            new LinkedBlockingQueue<Runnable>(128);
    // Initialization protected by sRunOnSerialPolicy lock.
    private static ThreadPoolExecutor sBackupExecutor;
    private static LinkedBlockingQueue<Runnable> sBackupExecutorQueue;

    private static final RejectedExecutionHandler sRunOnSerialPolicy =
            new RejectedExecutionHandler() {
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            android.util.Log.w(LOG_TAG, "Exceeded ThreadPoolExecutor pool size");
            // As a last ditch fallback, run it on an executor with an unbounded queue.
            // Create this executor lazily, hopefully almost never.
            synchronized (this) {
                if (sBackupExecutor == null) {
                    sBackupExecutorQueue = new LinkedBlockingQueue<Runnable>();
                    sBackupExecutor = new ThreadPoolExecutor(
                            BACKUP_POOL_SIZE, BACKUP_POOL_SIZE, KEEP_ALIVE_SECONDS,
                            TimeUnit.SECONDS, sBackupExecutorQueue, sThreadFactory);
                    sBackupExecutor.allowCoreThreadTimeOut(true);
                }
            }
            sBackupExecutor.execute(r);
        }
    };


    /**
    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     * An {@link Executor} that can be used to execute tasks in parallel.
@@ -217,8 +245,8 @@ public abstract class AsyncTask<Params, Progress, Result> {
    static {
    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
                new SynchronousQueue<Runnable>(), sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        threadPoolExecutor.setRejectedExecutionHandler(sRunOnSerialPolicy);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }
    }