Before you look at whatever code you want, first think about which parts of the thread pool should be:
The task queue is very good. The:blockingqueue<runnable> WorkQueue can be made directly by plugging the queue. 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. In Gettask can be seen, for example the following:
R = Workqueue.poll (KeepAliveTime, timeunit.nanoseconds);
Assuming that the thread pool is still very small at the time of the mission, it is now not necessary to put the task into the blocking queue and create a thread directly to execute it. This road will not go through when the "detour" to do. Because the blocking queue also has a capacity limit, you may fail when you try to put the task in.
Let's say I'm not going to try it, I'm just calling the plug-in method to get the main thread stuck here, which 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 has changed since the task was inserted. Then make sure that the task can be handled (not necessarily the task is finished.) may also be rejected), then the complete logic for submitting the 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. Assuming that you want to use a simple thread pool in spring, it's not necessary to write one yourself, directly with a ready-made configuration, for example:
---------- ---------- ---------- ----------END ---------- -------------------- ----------
[Java] Thread pool