I recently learned how to improve the thread pool and memory control.ProgramProgramming Technology in terms of running performance, I saw a good guy on the Internet, so I would like to share it with you.
[Sharing] principles and implementation of Java Thread Pool
In the past few days, I have been crazy about the source program. I have learned a lot of new knowledge (such as NiO), or a new technology, while making up for some gaps in previous knowledge.
The thread pool is one of them. When it comes to threads, we will think of the producers and consumers of the operating system, semaphores, synchronous control, and so on.
When we mention the pool, we will think of the database connection pool, but what about the thread pool?
Suggestions: Before reading this article, let's take a look at synchronization knowledge, especially the usage of syncronized synchronization keywords.
My understanding of synchronization is due to a book in my junior year. The title of the book seems to be a Java practice. This is a wonderful book, from theory to practice, from analysis. class bytecode analysis. Wow, I think it's hard to buy such exquisite books on the market. As a Java enthusiast, I think it is definitely worth reading.
What impressed me most about this book is the equal () method, which is a classic one!
There is also synchronization, which mentions some of my programming misunderstandings, how to use synchronization to improve performance in the past, etc. Through learning, I will further deepen my understanding of synchronization.
Brief Introduction
There are two ways to create a thread: Inherit the thread or implement runnable. Thread implements the runnable interface and provides an empty run () method. Therefore, whether it inherits the thread or implements runnable, it must have its own run () method.
A thread exists after being created. Call the START () method to start running (execute the run () method) and call wait to wait or call sleep to enter the sleep period, if the running is completed successfully, sleep is interrupted, or an exception occurs during the running process, the system exits.
Comparison between wait and sleep:
Sleep methods include sleep (long millis) and sleep (long millis, long Nanos). After the sleep method is called, the current thread enters the sleep period and the execution is suspended, however, this thread continues to have ownership of the monitored resources. After the sleep time is reached, the thread continues to execute until it is completed. If another thread interrupts the thread during the sleep period, the thread exits.
Wait methods include: Wait (), wait (long timeout), and wait (long timeout, long Nanos). After the wait method is called, the thread abandons the ownership of monitoring resources and enters the waiting state;
Wait (): Wait for other threads to call y () or notifyall () to enter the scheduling status and compete for monitoring with other threads. Wait () is equivalent to wait (0) and wait (0, 0 ).
Wait (long timeout): when other threads call y () or notifyall (), or the time reaches timeout seconds, or some other threads interrupt the thread, the thread enters the scheduling status.
Wait (long timeout, long Nanos): equivalent to wait (1000000 * timeout + Nanos), but the time unit is nanoseconds.
Thread Pool:
Multithreading technology mainly solves the problem of multiple threads in a processor unit. It can significantly reduce the idle time of the processor unit and increase the throughput of the processor unit.
Assume that the time required for a server to complete a task is T1 thread creation time, T2 thread execution time, and T3 thread destruction time.
If T1 + T3 is greater than t2, a thread pool can be used to improve server performance.
A thread pool consists of the following four basic components:
1. threadpool: used to create and manage thread pools, including creating thread pools, destroying thread pools, and adding new tasks;
2. Working thread (poolworker): a thread in the thread pool that is in the waiting state when no task exists and can be executed cyclically;
3. task: an interface that must be implemented by each task for the execution of tasks scheduled by the working thread. It mainly specifies the task entry and the final work after the task is executed, task execution status;
4. taskqueue: used to store unprocessed tasks. Provides a buffer mechanism.
The thread pool technology focuses on how to shorten or adjust T1 and T3 time to improve the performance of server programs. It arranges T1 and t3 in the start and end time periods or some idle time periods of the server program, so that when the server program processes customer requests, there will be no overhead of T1 and T3.
The thread pool not only adjusts the time periods generated by T1 and T3, but also significantly reduces the number of threads created. For example:
Assume that a server processes 50000 requests a day, and each request requires a separate thread. In the thread pool, the number of threads is generally fixed, so the total number of threads generated will not exceed the number of threads in the thread pool. If the server does not use the thread pool to process these requests, the total number of threads is 50000. Generally, the thread pool size is much smaller than 50000. Therefore, the server program that uses the thread pool does not waste time processing to create 50000 requests, thus improving efficiency.
/** Thread pool class. The worker thread acts as its internal class **/package Org. ymcn. util; import Java. util. collections; import Java. util. date; import Java. util. using list; import Java. util. list; import Org. apache. log4j. logger;/*** thread pool * Create thread pool, destroy thread pool, add new task ** @ author obullxl */public final class threadpool {Private Static logger = logger. getlogger (threadpool. class); Private Static logger tasklogger = logger. getlogger ("tasklogger"); Private sta TIC Boolean DEBUG = tasklogger. isdebugenabled (); // Private Static Boolean DEBUG = tasklogger. isinfoenabled ();/* Singleton */Private Static threadpool instance = threadpool. getinstance (); public static final int system_busy_task_count = 150;/* default number of threads in the pool */public static int worker_num = 5; /* Number of processed tasks */Private Static int taskcounter = 0; public static Boolean systemisbusy = false; Private Static list <Task> taskqueue = collections. synchronizedlist (new worker list <task> ();/* All threads in the pool */Public poolworker [] workers; private threadpool () {workers = new poolworker [5]; for (INT I = 0; I <workers. length; I ++) {workers [I] = new poolworker (I) ;}} private threadpool (INT pool_worker_num) {worker_num = pool_worker_num; workers = new poolworker [worker_num]; for (INT I = 0; I <workers. length; I ++ ){ Workers [I] = new poolworker (I) ;}} public static synchronized threadpool getinstance () {If (instance = NULL) return New threadpool (); Return instance ;} /*** Add a new task * wake up the task queue * @ Param newtask */Public void addtask (Task newtask) {synchronized (taskqueue) {newtask. settaskid (++ taskcounter); newtask. setsubmittime (new date (); taskqueue. add (newtask);/* wake up the queue and start to execute */taskqueue. notifyal L ();} logger.info ("Submit task <" + newtask. gettaskid () + ">:" + newtask.info ();}/*** add new tasks in batches * @ Param taskes */Public void batchaddtask (task [] taskes) {If (taskes = NULL | taskes. length = 0) {return;} synchronized (taskqueue) {for (INT I = 0; I <taskes. length; I ++) {If (taskes [I] = NULL) {continue;} taskes [I]. settaskid (++ taskcounter); taskes [I]. setsubmittime (new date (); taskque UE. add (taskes [I]);}/* wake up the queue and start to execute */taskqueue. policyall () ;}for (INT I = 0; I <taskes. length; I ++) {If (taskes [I] = NULL) {continue;} logger.info ("Submit task <" + taskes [I]. gettaskid () + ">:" + taskes [I]. info () ;}}/*** thread pool info * @ return */Public String getinfo () {stringbuffer sb = new stringbuffer (); sb. append ("\ ntask queue size:" + taskqueue. size (); For (INT I = 0; I <workers. lengt H; I ++) {sb. append ("\ nworker" + I + "is" + (Workers [I]. iswaiting ())? "Waiting. ":" running. ");} return sb. tostring ();}/*** destroy thread pool */Public synchronized void destroy () {for (INT I = 0; I <worker_num; I ++) {workers [I]. stopworker (); Workers [I] = NULL;} taskqueue. clear ();}/*** pool worker thread ** @ author obullxl */private class poolworker extends thread {private int Index =-1; /* whether the worker thread is valid */private Boolean isrunning = true;/* whether the worker thread can execute new tasks */private Boolean Iswaiting = true; Public poolworker (INT index) {This. index = index; Start ();} public void stopworker () {This. isrunning = false;} public Boolean iswaiting () {return this. iswaiting;}/*** execute the task cyclically * this may be the key to the thread pool */Public void run () {While (isrunning) {task r = NULL; synchronized (taskqueue) {While (taskqueue. isempty () {try {/* The task queue is empty. Wait for a new task to be added and wake up */taskqueue. wait (20);} catch (interru Ptedexception IE) {logger. Error (IE) ;}/ * retrieve task execution */r = (task) taskqueue. Remove (0);} If (R! = NULL) {iswaiting = false; try {If (Debug) {R. setbeginexceutetime (new date (); tasklogger. debug ("worker <" + index + "> Start execute task <" + R. gettaskid () + ">"); If (R. getbeginexceutetime (). gettime ()-R. getsubmittime (). gettime ()> 1000) tasklogger. debug ("longer waiting time. "+ r.info () +", <"+ index +">, time: "+ (R. getfinishtime (). gettime ()-R. getbeginexceutetime (). gettime ();}/* whether the task needs to be executed immediately */If (R. needexecuteimmediate () {New thread (R ). start ();} else {R. run ();} If (Debug) {R. setfinishtime (new date (); tasklogger. debug ("worker <" + index + "> finish task <" + R. gettaskid () + ">"); If (R. getfinishtime (). gettime ()-R. getbeginexceutetime (). gettime ()> 1000) tasklogger. debug ("Longer execution time. "+ r.info () +", <"+ index +">, time: "+ (R. getfinishtime (). gettime ()-R. getbeginexceutetime (). gettime () ;}} catch (exception e) {e. printstacktrace (); logger. error (e) ;}iswaiting = true; r = NULL ;}}}}}
/** Task interface class **/package Org. ymcn. util; import Java. util. date;/*** all task interfaces * Other tasks must inherit the access class ** @ author obullxl */public abstract class task implements runnable {// Private Static logger = logger. getlogger (task. class);/* generation time */private date generatetime = NULL;/* Submission execution time */private date submittime = NULL; /* start execution time */private date beginexceutetime = NULL;/* execution completion time */private date finishtime = NULL; private long taskid; public task () {This. generatetime = new date ();}/*** task execution entry */Public void run () {/*** execution Code ** Begintransaction (); ** a new task subtask = taskcore () may be generated during execution; ** committransaction (); ** a new threadpool will be added. getinstance (). batchaddtask (taskcore (); * //}/*** the core of all tasks, so the execution of special business logic ** @ throws exception */public abstract task [] taskcore () throws exception;/*** Use Database ** @ return */protected Abstract Boolean usedb (); /*** whether to immediately execute ** @ return */protected Abstract Boolean needexecuteimmediate (); /*** task info ** @ return string */public abstract string Info (); Public date getgeneratetime () {return generatetime;} public date getbeginexceutetime () {return beginexceutetime ;} public void setbeginexceutetime (date beginexceutetime) {This. beginexceutetime = beginexceutetime;} public date getfinishtime () {return finishtime;} public void setfinishtime (date finishtime) {This. finishtime = finishtime;} public date getsubmittime () {return submittime;} public void setsubmittime (date submittime) {This. submittime = submittime;} public long gettaskid () {return taskid;} public void settaskid (long taskid) {This. taskid = taskid ;}}