Before you look at whatever code you want, first think about which parts of the thread pool should be:
Task queue is very good, directly with the blocking queue can be:blockingqueue<runnable> workQueue. While threads are used to run tasks, it is natural that they should be continuously removed from the task queue to run, and we look at the implementation of the worker in Threadpoolexecutor:
private final class Worker implements Runnable {private final Reentrantlock Runlock = new Re Entrantlock ();p rivate Runnable firsttask;volatile long completedtasks; Thread thread;//runs taskprivate void RunTask (Runnable Task) {final Reentrantlock Runlock = This.runlock;runlock.lock (); try {//Check the status of the thread pool to infer whether to break if (Runstate < stop && thread.interrupted () && runstate >= stop) thread.inter Rupt (); Boolean ran = False;beforeexecute (thread, Task);//action before running the task try {task.run ();//task starts run ran = true;afterexecute (task , null);//Operation ++completedtasks after running the task;} catch (RuntimeException ex) {if (!ran) AfterExecute (task, ex);//operation after running the task throw ex;}} finally {Runlock.unlock ();}} Start running public void run () {try {Runnable task = Firsttask;firsttask = null;//from the thread pool and run while (task! = null) after the thread starts || (Task = Gettask ()) = null) {runTask (Task); task = null;}} Finally {Workerdone (this);}}}
It is possible to infer whether a worker is running a task by inferring that the Runlock is locked.
Of course, when the gettask fails, the worker's task ends, and we sometimes expect the thread to wait for a while, assuming that there is no task to reach the line friend exit.
This method of blocking threads in the queue can be seen in gettask, such as the following:
R = Workqueue.poll (KeepAliveTime, timeunit.nanoseconds);
When you get the job. Suppose today the thread pool is still very small. Now there is no need to put the task in the Jam queue. Just create a thread to execute it, and do it "around the bend" when the road does not go through. Because the blocking queue is also limited in capacity. You might fail when you try to put the task in.
Let me write the words will not try, but directly call the blocking method to plug the main thread here. This is actually not good:
- Not flexible enough
- The calling thread is blocked, wasting resources, and in fact it can be used to run the task
Assuming that you want to implement the reject strategy, implement the following interfaces:
public interface Rejectedexecutionhandler {void rejectedexecution (Runnable R, Threadpoolexecutor executor);}
It is possible that the status of the thread pool changes after the task is inserted, so that the task can be handled (not necessarily by the end of the task or rejected), then the complete logic of the commit task is as follows:
public void Execute (Runnable command) {if (command = = null) throw new NullPointerException ();//try to create a thread and run the task if (poolsize ; = Corepoolsize | | !addifundercorepoolsize (command)) {//try to put the thread into the Jam queue if (runstate = = RUNNING && workqueue.offer (command)) {if ( Runstate! = RUNNING | | Poolsize = = 0)//Ensure that the task will be processed ensurequeuedtaskhandled (command);} else if (!addifundermaximumpoolsize command)//assume that you can now create a thread to run the task, do not reject it ... Reject (command);}}
Ability to make changes in the current thread pool execution during the various thresholds can play a role. It's not necessary to write one yourself if you want to use a simple thread pool in spring. Directly with a ready-made configuration one will be able, for example:
---------- ---------- ---------- ----------END ---------- -------------------- ----------
[Java] Thread pool