Java self-made thread pool and java self-made thread
Personal blog: www.zarezone.cn
Java self-made Thread Pool
- 1. Introduction
- 1. Thread Pool
- . Thread Pool Function
- 1. 3. Advantages of Thread Pool
- 1.4.JDK built-in Thread Pool
- 1.4.1.ThreadPoolExecutor
- 2. Self-made Thread Pool
- 2. 1. Thread Pool subject class
- 2. Task Type
- 2. 3. Test class
Introduction Thread Pool
The basic idea of the thread pool is the idea of an object pool. It first opens up a piece of memory space and opens many threads waiting for tasks, once a task exists, the thread in the thread pool is used for the task. After the task ends, the thread is placed in the thread pool. The execution scheduling in the pool is managed by the thread pool manager.
Thread Pool Function
The role of the thread pool is to better manage the threads in the system. The number of threads can be set automatically or manually based on the system environment to achieve the best running effect.
Advantages of Thread Pool
What are the advantages of using a thread pool over not using a thread pool?
JDK built-in Thread Pool
Java. util. after the concurrent package, the thread pool is greatly optimized. Now we only need to use the provided API, we can easily use the built-in JDK thread pool, it provides great convenience for us to write our own programs.
ThreadPoolExecutor
Let's take a look at the complete construction method of ThreadPoolExecutor.
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
The parameter meanings are as follows:
CorePoolSize-Number of threads stored in the pool, including Idle threads. MaximumPoolSize-Maximum number of threads allowed in the pool. KeepAliveTime-when the number of threads exceeds the core, this is the maximum time for Idle threads to wait for new tasks before termination. Unit-keepAliveTime parameter time unit. WorkQueue-the queue used to keep the task before execution. This queue only keeps Runnable tasks submitted by the execute method. ThreadFactory-the factory used by the execution program to create a new thread. Handler-the handler used to block execution because it exceeds the thread range and queue capacity.
The following describes some common thread pools:
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}
Example
// Create a single-threaded thread pool ExecutorService pool = Executors. newSingleThreadExecutor (); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); // puts the Thread into the pool to execute pool.exe cute (t1 ); // close the thread pool. shutdown ();
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}
Example
// Create a thread pool that can reuse a fixed number of threads ExecutorService pool = Executors. newFixedThreadPool (2); // create and implement the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); // put the Thread into the pool and execute pool.exe cute (t1 ); // close the thread pool. shutdown ();
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}
Example
// Create a thread pool where new threads can be created as needed, but ExecutorService pool = Executors will be reused when previously constructed threads are available. newCachedThreadPool (); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); // puts the Thread into the pool to execute pool.exe cute (t1 ); // close the thread pool. shutdown ();
//// Create a thread pool that can be scheduled to run commands or periodically after a given delay. ExecutorService pool = Executors. newScheduledThreadPool (2); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); Thread t2 = new MyThread (); // Add the thread to the pool to execute pool.exe cute (t1); // use the delayed execution method pool. schedule (t2, 10, TimeUnit. MILLISECONDS); // closes the thread pool. shutdown ();
Self-made Thread Pool
Now let's write a thread pool by ourselves. This is just a simple thread pool that helps us better understand the principles of the thread pool.
Thread Pool subject class
MyThread. java
Import java. util. handler list;/***** @ author zlk * thread pool, inheriting ThreadGroup. ThreadGroup is used to process classes of a group of threads. It is a tree structure, its lower-level nodes can still be ThreadGroup objects */public class MyThreadPool extends ThreadGroup {private boolean isAlive; // It indicates whether the thread pool has enabled private writable list taskQueue; // task queue private int threadID in the thread pool; // thread IDprivate static int threadPoolID in the thread pool; // thread pool ID/*** create a new thread pool, numThreads is the number of threads in the pool * @ param numThreads */public MyThreadPool (int numThreads) {Super ("ThreadPool-" + (threadPoolID ++); // set the thread pool to "true", indicating that when all threads in the thread pool are destroyed, the thread pool is automatically destroyed. Super. setDaemon (true); this. isAlive = true; // create a task queue this. taskQueue = new worker list (); // start numThreads working threads for (int I = 0; I <numThreads; I ++) {new PooledThread (). start () ;}}/*** add new task * @ param Task */public synchronized void merge mtask (task) {if (! This. isAlive) {// throw the IllegalStateException exception throw new IllegalStateException ();} if (task! = Null) {// put the task at the end of the task queue this. taskQueue. add (task); // notify the worker thread to obtain the notify () ;}/ *** obtain the Task */protected synchronized task getTask () throws InterruptedException {// if the task list is empty and the thread pool is not closed, wait for the task while (this. taskQueue. size () = 0) {if (! This. isAlive) {return null;} wait () ;}// retrieve the first Task return (Task) this in the Task list. taskQueue. removeFirst ();}/*** close the thread pool. All threads stop and no longer execute the task */public synchronized void forceclose () {if (isAlive) {this. isAlive = false; // clear the task this. taskQueue. clear (); // terminate all threads in the thread pool this. interrupt () ;}}/*** close the thread pool and wait until all tasks in the thread pool are completed, but new tasks cannot be accepted */public void shutdown () {// notify other waiting threads of the message synchronized (this) {isAlive = false; y () ;}// wait until all threads are finished // first Creates a new thread array. The activeCount method gets the estimated number of active threads in the Thread pool. Thread [] threads = new Thread [this. activeCount ()]; // copy the active threads in the thread pool to the newly created thread array. int count = this. enumerate (threads); for (int I = 0; I <count; I ++) {try {// wait until the thread stops running threads [I]. join ();} catch (InterruptedException e) {e. printStackTrace () ;}}/ *** internal class, used to execute the task's working Thread */private class PooledThread extends Thread {// constructor public PooledThread () {// The first parameter is the object in the thread group of the thread, that is, the object in the current thread pool. // The second parameter is the thread name super (M YThreadPool. this, "PooledThread-" + (threadID ++);} public void run () {// If the thread is not terminated while (! IsInterrupted () {// obtain Task task = null; try {Task = getTask ();} catch (InterruptedException e) {e. printStackTrace ();} // as long as the task list in the thread pool is not empty, the getTask method can always get a task. // If getTask () returns null, it indicates that there are no tasks in the thread pool and the thread pool has been closed. If (task = null) {return;} // run the task and absorb exceptions. try {task. perform ();} catch (Throwable t) {// when a thread in the thread group has an uncaptured exception, the JVM will go back and call the uncaughtException method uncaughtException (this, t );}}}}}
Task Type
Task. java// Serves as the total interface for executing tasks
Public interface Task {/*** execution Task * throws Exception possible exceptions during execution */public void perform () throws Exception ;}
MyTask. java// Implement the task interface
Public class MyTask implements Task {private int taskID = 0; // The IDpublic MyTask (int id) {this. taskID = id;}/*** perform method for implementing the Task interface */@ Overridepublic void perform () throws Exception {System. out. println ("MyTask" + taskID + ": start"); // sleep for one second try {Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();} System. out. println ("MyTask" + taskID + ": end ");}}
Test class
PoolTest. java// Test the self-made Thread Pool
Import com. zale. threadpool. myTask; import com. zale. threadpool. myThreadPool; public class PoolTest {public static void main (String [] args) {int numThreads = 3; // Number of threads in the thread pool MyThreadPool threadPool = new MyThreadPool (numThreads ); // generate the thread pool int numTasks = 10; // number of tasks // run the task for (int I = 0; I <numTasks; I ++) {threadPool. performTask (new MyTask (I);} // close the thread pool and wait for all tasks to complete threadPool. shutdown ();}}
Are you familiar with java thread pools?
Functions in java are actually a lot of encapsulated Code (the code is often used, so it is encapsulated into a simple function for you to call ), the process of calling a function is to execute the Code. In addition, it is built on a mobile phone and a java platform on a pda, generally, your java program is parsed through the platform into a program that can be run by the operating system. java programs are like gold, and it is impossible to directly buy things, the java parser is like a bank. You can use it if you change gold to a bank, and the operating system is like a country. You can change gold to USD or RMB, euro ....... the same is true for java. The parser compiles your java program into different s programs in different environments to implement cross-platform functions, however, similar to MFC, it cannot be used in the same way as java. It is often the same principle that the renminbi cannot be used in the United States to directly buy things.
Java thread pool Synchronization
You can set a standard flag value to 1 2 3, and then the Before thread continues wait until the flag changes to 1. After the execution, the flag changes to 2, the MyThread thread continues wait until the flag changes to 2. After the execution, the flag changes to 3,
The After thread continues wait until the flag changes to 3 and ends After execution.
In fact, multithreading is mainly used for concurrency. If it is sequential execution, it is better to put it in a thread.