Java handwriting thread pool (first generation)
I often use thread pools, so today I have a sudden idea and will have many shortcomings when writing a thread pool by hand. Please be tolerant. Because this is also the first generation version, it will be more complete in the future.
Handwriting thread pool - define parameters
private final AtomicInteger taskcount=new AtomicInteger(0); private final AtomicInteger threadNumber=new AtomicInteger(0); private volatile int corePoolSize; private final Set<> workers; private final BlockingQueue<Runnable> waitingQueue; private final String THREADPOOL_NAME="MyThread-Pool-"; private volatile boolean isRunning=true; private volatile boolean STOPNOW=false; private final ThreadFactory threadFactory;
- taskcount: Number of tasks executed
- threadNumber: thread number, incremented from 0.
- corePoolSize: Number of core threads
- Workers: Worker threads
- waitingQueue: Waiting for queue
- THREADPOOL_NAME: Thread name
- isRunning: Whether to run
- STOPNOW: Should I stop immediately
- threadFactory: thread factory
Handwriting thread pool-constructor
public MyThreadPoolExecutor(int corePoolSize, BlockingQueue<Runnable> waitingQueue,ThreadFactory threadFactory) { =corePoolSize; =new HashSet<>(corePoolSize); =waitingQueue; =threadFactory; //Thread preheating for (int i = 0; i < corePoolSize; i++) { new MyWorker(); } }
This constructor functions:
1: Assign values to the parameters.
2: Thread warm-up. Call MyWorker's constructor according to the size of corePoolSize. We can see what the MyWorker constructor does.
final Thread thread; //For each MyWorker MyWorker(){ Thread td = (this); (THREADPOOL_NAME+()); =td; (); (this); }
- The MyWorker constructor generates Thread for the current object through a thread factory;
- And set the thread name: MyThread-Pool-self-increment thread number;
- Then call the start method of the thread to start the thread;
- Finally, it is stored in the workers Set collection, so that thread reuse can be implemented.
Handwriting thread pool - default constructor
public MyThreadPoolExecutor(){ this(5,new ArrayBlockingQueue<>(10), ()); }
- The assignment initial value of the default constructor:
- corePoolSize:5
- waitingQueue: new ArrayBlockingQueue<>(10), a finite blocking queue of length 10
- threadFactory:()
Handwriting thread pool-execute method
public boolean execute(Runnable runnable) { return (runnable); }
- In essence, it is actually putting Runnable (task) into the waitingQueue.
Handwriting thread pool - handle tasks
@Override public void run() { //Cyclic receiving tasks while (true) { if((!isRunning&&()==0)||STOPNOW) { break; }else { Runnable runnable = (); if(runnable!=null){ (); ("task==>"+()); } } } }
In essence, it is a dead loop receiving task, and the exit conditions are as follows:
- Elegant exit. When isRunning is false and the queue size of waitingQueue is 0 (that is, there is no task)
- Violent exit. When STOPNOW is true, it means that the shutdownNow method has been called
- The else statement block will keep getting tasks as tasks! When =null, the run method is called to handle the task.
Handwritten thread pool - elegantly close thread pool
public void shutdown() { =false; }
Handwriting thread pool - Brutal shutdown thread pool
public void shutdownNow() { =true; }
Handwritten thread pool - source code
- Handwritten thread pool source code
package ; import ; import ; import ; import ; import ; import ; import ; /** * Thread pool class * @author You Zhengjie */ public class MyThreadPoolExecutor { private final AtomicInteger taskcount=new AtomicInteger(0);//Number of tasks executed private final AtomicInteger threadNumber=new AtomicInteger(0); //Thread number private volatile int corePoolSize; //Number of core threads private final Set<> workers; //Work thread private final BlockingQueue<Runnable> waitingQueue; //Waiting for queue private final String THREADPOOL_NAME="MyThread-Pool-";//Thread name private volatile boolean isRunning=true; //Whether it works private volatile boolean STOPNOW=false; //Stop immediately private final ThreadFactory threadFactory; //Thread Factory public MyThreadPoolExecutor(){ this(5,new ArrayBlockingQueue<>(10), ()); } public MyThreadPoolExecutor(int corePoolSize, BlockingQueue<Runnable> waitingQueue,ThreadFactory threadFactory) { =corePoolSize; =new HashSet<>(corePoolSize); =waitingQueue; =threadFactory; //Thread preheating for (int i = 0; i < corePoolSize; i++) { new MyWorker(); } } /** * MyWorker is each of our thread objects */ private final class MyWorker implements Runnable{ final Thread thread; //For each MyWorker MyWorker(){ Thread td = (this); (THREADPOOL_NAME+()); =td; (); (this); } @Override public void run() { //Cyclic receiving tasks while (true) { //Loop exit conditions: //1: When isRunning is false and the queue size of waitingQueue is 0 (that is, there is no task), it will exit gracefully. //2: When STOPNOW is true, it means that the shutdownNow method has been called for brute force exit. if((!isRunning&&()==0)||STOPNOW) { break; }else { //Continuously pick up tasks and be a task! When =null, the run method is called to handle the task. Runnable runnable = (); if(runnable!=null){ (); ("task==>"+()); } } } } } public boolean execute(Runnable runnable) { return (runnable); } //Elegantly closed public void shutdown() { =false; } // Violent Close public void shutdownNow() { =true; } }
- Test using handwritten thread pool code
package ; import ; import ; import ; public class ThreadPoolTest { public static void main(String[] args) { MyThreadPoolExecutor myThreadPoolExecutor = new MyThreadPoolExecutor (5,new ArrayBlockingQueue<>(6), ()); for(int i=0;i<10;i++){ int finalI = i; (()->{ (().getName()+">>>>"+ finalI); }); } (); // (); } }
question
Why do custom thread pool execute fewer tasks sometimes?
That's because waitingQueue is full and can't let go of the task, causing the task to be discarded, which is equivalent to the DiscardPolicy rejection policy
Solutions are:
1: Set the maximum number of threads to automatically expand the thread pool.
2: Increase the capacity of waitingQueue
Finally: Because this is the first version of the thread pool I handwritten, it basically implements the reuse function of the thread pool. However, there are still many unfinished articles. In the future, there will be several more completed articles to upgrade the current handwritten thread pool.
In the future, we will continue to publish blog posts about the author's handwritten Spring framework, handwritten Tomcat framework and other frameworks! ! ! ! !
This is the article about how to write Java thread pools step by step from the student perspective. For more related Java thread pool content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!