This article is participating in the “Java Subject month – Java Debug Notes activity”, see more detailsActive link
Personal nagging
I split one article into seven, and fortunately, they all survived to participate in Nugget’s Java Note Debug. I heard that if I put it together again, it might become a switch. But I found that together they only had a 0.0001 success rate.
preface
The thread pool source analysis on the Internet is too much, here do not say the principle. Write a simple thread pool by referring to it directly. I remember Google’s Volley wrote something simpler and more violent, just straight for loop out a few threads and then block the read task.
Start step-by-step…. Remember to hit the likes (⊙o⊙)…
I strongly recommend reading the first two articles first
On the key
Java operator literacy
JAVA thread pool source in-depth state value analysis
Let me draw a flow chart
We follow the flow chart and write the code.
The core thread processing class
Let’s define a couple of variables. ThreadPoolExecutor uses AtomicInteger, which represents the thread state and the number of threads at work, in order to reduce lock contention. Not for simplicity’s sake. Let me write another article. This state is kind of interesting.
/** * Specifies the maximum number of tasks to be queued. */ private final int maximumPoolSize; Private volatile int threadSize = 3; private volatile int threadSize = 3; / private final BlockingQueue<Runnable> workQueue; / private final BlockingQueue<Runnable> workQueue; Private Final AtomicInteger threadCount = new AtomicInteger(0); /** * Record the number of threads currently running */ Private Final AtomicInteger threadCount = new AtomicInteger(0);Copy the code
Processing tasks
There are three steps:
The new thread
startThread(count);
If the current running thread has not reached the maximum, continue to create new threads
Add tasks
workQueue.add(task);
If the task queue is full, join it. Full, that is, the number of tasks has reached the maximum maximumPoolSize, and the queue is rejected.
Take the task
workQueue.take(); I’ll talk more about that.
There is no write-thread reclaiming, and the allowCoreThreadTimeOut of ThreadPoolExecutor is not reclaiming by default. Because it is common to queue processes that are blocked, this is called a blocking queue. In some systems, blocked processes are queued in multiple ways, depending on the reason for blocking.
@param task */ public void execute(Runnable task) { (threadSize) if (threadCount. The get () < threadSize) {int count = threadCount. IncrementAndGet (); System.out.println("count: "+ count); // Start multiple threads to fetch the task. The core is here. startThread(count); } int workQueueSize=workQueue.size(); If (workQueueSize>maximumPoolSize){system.out.println (" The maximum number of jobs is exceeded. Thread Count: "+ workQueueSize); return; } system.out.println ("thread Count: "+ threadcount.get ()); // Add the task, warning: Queue full will throw an exception if the Queue size exceeds the defined Queue size. workQueue.add(task); }Copy the code
Extract tasks and process tasks
The core is workqueue.take (); , loop endlessly to fetch tasks, and block without tasks.
After the task is fetched, task.run() is called to process the task.
Thread thread = new Thread() { @Override public void run() { super.run(); While (true) {try {// Block without a task, BlockingQueue, depending on the type you pass. Runnable task = workQueue.take(); System.out.println("workQueue size:"+workQueue.size() + "::" + getName() + "--:" + task.toString()); // Simulate the processing task, and the time. task.run(); } catch (Exception e) { e.printStackTrace(); }}}}; thread.setName("tag:" + nameTag); thread.start();Copy the code
At this point, the core code is all written. Isn’t that simple. Take out the comments and you don’t see 50 lines.
The code for the test class
Let’s write the code for the test class:
Define the number of core threads as 3
Define the maximum number of tasks as 10 and set it to small so that you can easily observe the addition of rejected tasks.
The blocking queue is LinkedBlockingQueue and is unbounded.
Over and out.
SimpleThreadPoolExecutor executor = new SimpleThreadPoolExecutor (3, 10, new LinkedBlockingQueue < > ()); Execute (() -> {// simulate the time processing task processTask(); }); /** * Simulate task */ private static void processTask() {int sleep = new Random().nextint (10) * 1000; System.out.println(" Simulated processing task time: "+sleep); try { Thread.sleep(sleep); } catch (InterruptedException e) { e.printStackTrace(); }}Copy the code
The source address
Source address, simple thread pool
conclusion
Now you can write a simple thread pool by hand, simple, small, but complete.
My knowledge is limited, if there is a description of the error, I hope the tiger is right.
Look at thisLike you owe me a thumbs up.