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.