In the past two years of working in Android, through researching Android source code, I will also have some understanding of Java concurrent processing of multi-threading.
So the question is, how to implement a serial thread pool?
What is a serial thread pool?
In other words, our Runnable objects should have a queue mechanism, which enters from the tail of the queue in sequence, and selects Runnable from the head of the queue for execution.
Since we have a idea, let’s consider the required data structure?
Since we are inserting the Runnable object from the end of the queue and executing the Runnable object from the head of the queue, we naturally need a queue. Java's SDK has provided us with a good queue data structure, such as double-ended queue: ArrayDeque<Runnable>.
import java.util.ArrayDequ;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;/** * Created by wzy on 16-1-5. */public class SerialExecutor { private Runnable mActive; private ArrayDequ<Runnable> mArrayDequ = new ArrayDequ<>(); 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 LinkedBlockingDeque<>(128); private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { return new Thread(r, "Serial thread #" + mCount.getAndIncrement()); } }; private static final ThreadPoolExecutor THREAD_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); public synchronized void execute(final Runnable r) { mArrayDequ.offer(new Runnable() { @Override public void run() { try { r.run(); } finally { scheduleNext(); } } }); // When the first time you join the queue, mActive is empty, so you need to call the scheduleNext method manually if (mActive == null) { scheduleNext(); } } private void scheduleNext() { if ((mActive = mArrayDequ.poll()) != null) { THREAD_EXECUTOR.execute(mActive); } } public static void main(String[] args) { SerialExecutor serialExecutor = new SerialExecutor(); for (int i = 0; i < 10; i ++) { final int j = i; serialExecutor.execute(new Runnable() { @Override public void run() { System.out.println("The num is :" + (j + 1)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }}The execution results are as follows:
The num is :1
The num is :2
The num is :3
The num is :4
The num is :5
The num is :6
The num is :7
The num is :8
The num is :9
The num is :10
The above is all the content of this article about the analysis of serial thread pool instances of Java concurrency, and I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!