Personal blog: www.zalezone.cn
Java self-made thread pool No Comments
- 1. introduction
- 1.1. thread pool
- 1.2. thread pool effect
Li class= "toc-item toc-level-2" > 1.3. thread pool benefits
- 1.4. JDK comes with thread pool
- 1.4.1. threadpoolexecutor
- 2. homemade thread pool
- 2.1. thread pool principal class
- 2.2. Task Class
- 2.3. Test class
Introduction thread pool
The basic idea of the thread pool is a kind of object pool idea, first open up a piece of memory space, open a lot of waiting for the task of the thread, once the task appears to use threads in the thread pool to do the task, wait until the end of the task to put the thread pool, the execution schedule of the pool is managed by the thread pool manager.
Thread pool Role
The role of the thread pool is to better manage the threads in the system, depending on the environment of the system, can automatically or manually set the number of threads, to achieve the best performance.
Thread Pool Benefits
What are the advantages of using a thread pool without using a thread pool?
- Reduces the number of times a thread is created and destroyed, and each worker thread can be reused for reuse after it is exhausted.
- Can control the size of the thread pool according to the ability of the system, prevent the server from consuming too much memory without using the thread pool and not managing the threads well.
JDK comes with thread pool
Since JDK1.5 was added to the java.util.concurrent package, the thread pool has been greatly optimized, and now as long as it is used in accordance with the API provided, we can easily use the thread pool that comes with the JDK, providing great convenience when writing our own programs.
Threadpoolexecutor
Let's take a look at the complete construction method of Threadpoolexecutor
1 |
Threadpoolexecutor (intintlong keepalivetime, timeunit unit, blockingqueue<runnable > WorkQueue, threadfactory threadfactory, Rejectedexecutionhandler handler) |
For the inside of the parameter meaning is as follows:
execute 方法提交的 Runnable 任务。threadFactory - 执行程序创建新线程时使用的工厂。handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
Here are some common thread pools:
Newsinglethreadexecutor: Creates a single thread pool. This thread pool has only one thread at work, which is equivalent to single-threaded serial execution of all tasks. If this unique thread ends because of an exception, a new thread will replace it. This thread pool guarantees that the order in which all tasks are executed is performed in the order in which the tasks are submitted.
The corresponding construction method
123456 |
Public Static Newsinglethreadexecutor () { returnnew finalizabledelegatedexecutorservice (new Threadpoolexecutor ( 1 1, 0L, timeunit.milliseconds, new linkedblockingqueue<runnable> ())); } |
使用方法示例
12345678 |
//Create a single thread pool Executorservice pool = Executors.newsinglethreadexecutor (); //created implements the Runnable interface object, the thread object of course also implements the Runnable interface New MyThread (); //Put the thread into the pool for execution pool.execute (t1); //Close thread pool pool.shutdown (); |
Newfixedthreadpool: Creates a fixed-size thread pool. Each time a task is committed, a thread is created until the thread reaches the maximum size of the threads pool. Once the maximum size of the thread pool is reached, the thread pool will be replenished with a new thread if it ends up executing an exception.
The corresponding construction method
12345 |
Public Static Newfixedthreadpool (int nthreads) { returnnew threadpoolexecutor (Nthreads, nthreads, 0L, Timeunit.milliseconds, New linkedblockingqueue<runnable> ()); } |
使用方法示例
12345678 |
//Create a thread pool that can reuse a fixed number of threads Executorservice pool = Executors.newfixedthreadpool (2); //created implements the Runnable interface object, the thread object of course also implements the Runnable interface New MyThread (); //Put the thread into the pool for execution pool.execute (t1); //Close thread pool pool.shutdown (); |
Newcachedthreadpool: Creates a cacheable, non-bounded pool. If the size of the thread pool exceeds the thread required to process the task, then a partially idle (60 second non-performing task) thread is reclaimed, and when the number of tasks increases, the thread pool can intelligently add new threads to handle the task. This thread pool does not limit the size of the thread pool, and the thread pool size is entirely dependent on the maximum thread size that the operating system (or JVM) can create.
The corresponding construction method
12345 |
Public Static Newcachedthreadpool () { returnnew threadpoolexecutor (0, Integer.max_value, L, Timeunit.seconds, new synchronousqueue<runnable> ()); } |
使用方法示例
12345678 |
//Create a thread pool that can create new threads as needed, but reuse them when previously constructed threads are available //created implements the Runnable interface object, the thread object of course also implements the Runnable interface New MyThread (); //Put the thread into the pool for execution pool.execute (t1); //Close thread pool pool.shutdown (); |
newscheduledthreadpool: Create a thread pool of unlimited size. This thread pool supports the need to schedule and periodically perform tasks.
Examples of how to use
1234567891011 |
Executorservice pool = Executors.newscheduledthreadpool (2); //created implements the Runnable interface object, the thread object of course also implements the Runnable interface New New MyThread (); //Put the thread into the pool for execution pool.execute (t1); //Using the method of deferred execution style Ten //Close thread pool pool.shutdown (); |
Homemade thread pool
Now let's write a thread pool by ourselves. This is just a simple thread pool that helps us to better understand the thread pool principle.
Thread pool Principal class
Mythread.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 6667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611 7118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
ImportJava.util.LinkedList;/*** *@authorZLK * thread pool, inheriting Threadgroup,threadgroup class used to process a set of threads, which is a tree structure whose underlying nodes can still be threadgroup objects */ Public class mythreadpool extends threadgroup {Private BooleanisAlive;//Flag thread pool is turned on PrivateLinkedList Taskqueue;//Task queue in a thread pool Private intThreadID;//thread ID in thread pool Private Static intThreadpoolid;//thread pool ID /*** Create a new thread pool, Numthreads is the number of threads in the pool *@paramNumthreads * * Public Mythreadpool(intNumthreads) {Super("threadpool-"+ (threadpoolid++));//Set the thread pool is the Daemon property to true, which means that when all threads in the thread pool are destroyed, that pool is automatically destroyed. Super. Setdaemon (true); This. isAlive =true;//Create a new task queue This. Taskqueue =NewLinkedList ();//Start numthreads a worker thread for(inti =0; i < numthreads; i++) {NewPooledthread (). Start (); } }/*** Add new tasks *@paramTask */ Public synchronized void Performtask(Task Task) {if(! This. isAlive) {//thread pool is closed throws IllegalStateException exception Throw NewIllegalStateException (); }if(Task! =NULL) {//Put the task at the end of the task queue This. Taskqueue.add (Task);//Notify worker thread to take taskNotify (); } }/*** Get tasks */protected synchronizedTaskGettask()throwsinterruptedexception {//If the task list is empty and the thread pool is not closed, continue waiting for the task while( This. taskqueue.size () = =0) {if(! This. isAlive) {return NULL; } wait (); }//Take the first task in a task list return(Task) This. Taskqueue.removefirst (); }/*** Close thread pool, all threads stop, no longer perform task */ Public synchronized void Forceclose() {if(isAlive) { This. isAlive =false;//Cleanup task This. Taskqueue.clear ();//Terminates all threads in the thread pool This. interrupt (); } }/*** Closes the thread pool and waits for all tasks in the thread pools to be completed, but cannot accept new tasks */ Public void shutdown(){//Notifies other waiting threads that the thread pool is closed message synchronized( This) {isAlive =false; Notify (); }//wait for all threads to complete //Create a new array of threads first. Activecount method Gets the estimated number of active threads in the thread poolthread[] Threads =Newthread[ This. Activecount ()];//Copy the active thread from the thread pool to the newly created thread array intCount = This. enumerate (threads); for(inti =0; I < count; i++) {Try{//wait for thread to run endThreads[i].join (); }Catch(Interruptedexception e) {E.printstacktrace (); } } }/*** Internal class, the worker thread to perform the task */Private class pooledthread extends Thread {//Construction method Public Pooledthread() {//The first parameter is the object of the thread group where the thread is located, that is, the object of the current thread pool //The second parameter is the thread name Super(Mythreadpool. This,"pooledthread-"+ (threadid++)); } Public void Run() {//If the thread is not terminated while(!isinterrupted ()) {//Get TasksTask task =NULL;Try{task = Gettask (); }Catch(Interruptedexception e) {E.printstacktrace (); }//As long as the task list of the thread pool is not empty, the Gettask method will always get a task. //If Gettask () returns NULL, it indicates that no tasks are already in the thread pool and that the thread pools have been closed. if(Task = =NULL){return; }//running tasks, absorbing anomalies Try{Task.perform (); }Catch(Throwable t) {//When a thread in a thread group has an uncaught exception that occurs, the JVM goes back to calling the Uncaughtexception methodUncaughtexception ( This, t); } } } } } |
Task class
Task.java //As the total interface for performing tasks
1234567 |
Public interfaceTask { /** * Perform task * throws Exception possible exception during execution */public void perform()throws Exception;} |
Mytask.java //implements the task interface
123456789101112131415161718192021222324 |
Public class mytask implements Task {Private intTaskID =0;//The ID of the task Public MyTask(intID) { This. TaskID = ID; }/*** Perform method for implementing the Task interface */@Override Public void Perform()throwsException {System.out.println ("MyTask"+ TaskID +": Start");//Sleep one second Try{Thread.Sleep ( +); }Catch(Exception e) {E.printstacktrace (); } System.out.println ("MyTask"+ TaskID +": End"); }} |
Test class
Pooltest.java //test homemade thread pool
1234567891011121314151617181920 |
ImportCom.zale.threadpool.MyTask;ImportCom.zale.threadpool.MyThreadPool; Public class pooltest { Public Static void Main(string[] args) {intNumthreads =3;//number of threads in the thread poolMythreadpool ThreadPool =NewMythreadpool (numthreads);//Generate thread pool intNumtasks =Ten;//Number of tasks //Run Tasks for(inti =0; i < numtasks; i++) {Threadpool.performtask (NewMyTask (i)); }//Close thread pool and wait for all tasks to completeThreadpool.shutdown (); }} |
Java self-made thread pool