First, the schematic diagram:
Before the code, you should first add the core points of the thread pool construct
- Thread constructor number of core threads and maximum number of threads
- Line constructor really working thread
worker
- Line constructor The queue used to access tasks
BlockingQueue
- tasks in a thread
task
The implementation of this example simplifies some, only implements the Blockingqueue storage task, then each worker takes the task and executes, see the code below
First define a thread pool Threadexcutor
classthreadexcutor{//Create Private volatile BooleanRUNNING =true; //All tasks are placed in a queue, allowing the work thread to consume Private Staticblockingqueue<runnable> queue =NULL; Private FinalHashset<worker> workers =NewHashset<worker>(); Private FinalList<thread> threadlist =NewArraylist<thread>(); intpoolsize = 0;//Pool Size intcurrentsize = 0;//How many threads are created Booleanshutdown =false; PublicThreadexcutor (intpoolsize) { This. poolsize =poolsize; Queue=NewLinkedblockingqueue<runnable>(poolsize); } //submit a task to the thread pool Public voidexec (Runnable Runnable) {if(runnable = =NULL)Throw NewNullPointerException (); if(CurrentSize < Poolsize) {//Current number of worker threads is less than pool sizeAddthread (runnable);//Create a thread to perform a task}Else{ //System.out.println ("offer" + runnable.tostring () + "" + queue.size ()); Try{queue.put (runnable); } Catch(interruptedexception e) {e.printstacktrace (); } } } Public voidAddthread (Runnable Runnable) {currentsize++; Worker worker=NewWorker (runnable);//Add a runnable task to the queue while instantiating a workerWorkers.add (worker); Thread T=NewThread (worker);//Create a thread, the worker itself implements the Runnable interfaceThreadlist.add (t); Try{T.start (); //Open the Run method of the thread execution worker}Catch(Exception e) {e.printstacktrace (); } } Public voidshutdown () {RUNNING=false; if(!Workers.isempty ()) { for(Worker worker:workers) {worker.interruptifidle (); //Call the worker member method to break the thread itself}} Shutdown=true; Thread.CurrentThread (). interrupt (); } //let's leave a place for the inner class worker ... }
It then defines an inner class worker, which is used to perform each task, adding tasks to the thread after the thread pool is created, each of which is initiated by the worker one by one.
//Worker ThreadsclassWorkerImplementsrunnable{ PublicWorker (Runnable Runnable) {queue.offer (Runnable); } //The worker class implements the Runnable interface, and the Run method loops through the queue to execute the task until the pool shutdown@Override Public voidrun () { while(RUNNING) {Runnable task=NULL; if(Shutdown = =false){ Try{Task=Gettask (); Task.run (); } Catch(interruptedexception e) {e.printstacktrace (); } } } } PublicRunnable Gettask ()throwsinterruptedexception {returnQueue.take (); } Public voidInterruptifidle () {//Idle -Free for(Thread thread:threadlist) {System.out.println (Thread.getname ()+ "Interrupt"); Thread.Interrupt (); } } }
The first thing to note is that this worker is an internal class that is declared within a thread pool.
exec method
How the Worker Works
When the worker is instantiated, it joins a task into the queue, that is, when the worker thread is instantiated, the worker thread is also a task that is added to the thread pool. Then there is the Run method, which is the thread that the thread called the Start method to generate, and the worker-tuned run method does not generate a new thread. is a loop that has been constantly fetching tasks from the queue and then executing them. As you can see, the method of fetching the queue is take (), which means that if the queue is empty, the queue is blocked if the data is not available.
then see Shutdown ()
You work hard every day, suddenly received the above orders, said live not to take, first stop, when you have not made clear of the situation, then your leadership and you opened up, said the company to fall, you first laid off, I also have to be laid off. This is what shutdown does, shutdown must be the main thread to stop the worker thread.
The shutdown method is not to use a thread-like force to stop the pointers, but to first use an identifier to tell the worker, not to take the task again. Then notify the worker thread that you can interrupt()
, when all the threads stop and remember to stop the main thread, so that a simple task of the thread pool is complete.
Let's test it out:
Public classmain{ Public Static voidMain (string[] args) {threadexcutor excutor=NewThreadexcutor (3); for(inti = 0; I < 3; i++) {excutor.exec (NewRunnable () {@Override Public voidrun () {System.out.println ("Thread" + thread.currentthread (). GetName () + "Working for Me"); } }); } excutor.shutdown (); } }
ImportJava.util.*;Importjava.util.concurrent.*; Public classmain{ Public Static voidMain (string[] args) {threadexcutor excutor=NewThreadexcutor (3); for(inti = 0; i < 1000; i++) {excutor.exec (NewRunnable () {@Override Public voidrun () {System.out.println ("Thread" + thread.currentthread (). GetName () + "Working for Me"); } }); } excutor.shutdown (); } }classthreadexcutor{//Create Private volatile BooleanRUNNING =true; //All tasks are placed in a queue, allowing the work thread to consume Private Staticblockingqueue<runnable> queue =NULL; Private FinalHashset<worker> workers =NewHashset<worker>(); Private FinalList<thread> threadlist =NewArraylist<thread>(); intpoolsize = 0;//Pool Size intcurrentsize = 0;//How many threads are created Booleanshutdown =false; PublicThreadexcutor (intpoolsize) { This. poolsize =poolsize; Queue=NewLinkedblockingqueue<runnable>(poolsize); } //submit a task to the thread pool Public voidexec (Runnable Runnable) {if(runnable = =NULL)Throw NewNullPointerException (); if(CurrentSize < Poolsize) {//Current number of worker threads is less than pool sizeAddthread (runnable);//Create a thread to perform a task}Else{ //System.out.println ("offer" + runnable.tostring () + "" + queue.size ()); Try{queue.put (runnable); } Catch(interruptedexception e) {e.printstacktrace (); } } } Public voidAddthread (Runnable Runnable) {currentsize++; Worker worker=NewWorker (runnable);//Add a runnable task to the queue while instantiating a workerWorkers.add (worker); Thread T=NewThread (worker);//Create a thread, the worker itself implements the Runnable interfaceThreadlist.add (t); Try{T.start (); //Open the Run method of the thread execution worker}Catch(Exception e) {e.printstacktrace (); } } Public voidshutdown () {RUNNING=false; if(!Workers.isempty ()) { for(Worker worker:workers) {worker.interruptifidle (); //Call the worker member method to break the thread itself}} Shutdown=true; Thread.CurrentThread (). interrupt (); } //let's leave a place for the inner class worker . classWorkerImplementsrunnable{ PublicWorker (Runnable Runnable) {queue.offer (Runnable); } //The worker class implements the Runnable interface, and the Run method loops through the queue to execute the task until the pool shutdown@Override Public voidrun () { while(RUNNING) {Runnable task=NULL; if(Shutdown = =false){ Try{Task=Gettask (); Task.run (); } Catch(interruptedexception e) {e.printstacktrace (); } } } } PublicRunnable Gettask ()throwsinterruptedexception {returnQueue.take (); } Public voidInterruptifidle () {//Idle -Free for(Thread thread:threadlist) {System.out.println (Thread.getname ()+ "Interrupt"); Thread.Interrupt (); } } } }
Http://www.cnblogs.com/wxwall/p/7050698.html
Implement a simple thread pool yourself