Multithreading is common in Java development, and Java also provides the Thread class Thread to make it easy to create a Thread as shown in the code below
new Thread(){
@Override
public void run() {... } }.start();Copy the code
-
There are several disadvantages to creating new threads this way
- You need to create one every time you want to start a new thread, which is poor performance
- Threads are created randomly and there is no unified management
- The interrupt of the thread cannot be done
-
To address these issues, we need to use thread pools to manage threads.
The java.util.concurrent package in Java SE5 provides executors to manage thread objects. Executtor is an interface, and ExecutorService inherited the Excutor interface. ExecutorService is a lifecycle Executor that knows how to build the right context to execute Runnable objects. The ExecutorService object is the Thread pool in Java by using the static method of execorating
Executor public interface Executor {/** * Executes the Givencommand at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
Copy the code
-
Java’s four thread pools
-Java provides four thread pools: FixedThreadPool, CachedThreadPool, ScheduledThreadPool, and SingleThreadExector
-
FixedThreadPool
- * If the thread pool is created by using Executors’ newFixedThreadPool() method, the number of threads in the pool is fixed. If the thread pool is idle, the system will not recycle it unless it is shut down. When all its threads are performing tasks, the new thread will come out of the waiting state, and wait until there are idle threads, the new task will be executed. If there are idle threads in the thread pool when the new task is added, it means that it can respond to the task quickly.
public static ExecutorService newFixedThreadPool(int nThreads) { returnnew ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } /* * Runnable r=newRunnable(){ @Override run() {... } } ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(r)Copy the code
-
CachedThreadPool
-
* * If the thread count is up to the end of Executors, the thread will execute the task immediately following the closure-newcachedThreadpool () method. * / * If the thread count is up to the end of Executors, the thread count will be infinite. But its each thread is under idle timeout mechanism, this time for 60 seconds, as long as the thread is idle for more than 60 seconds this thread will be recycled, if all the thread is in the idle state, and more than 60 seconds, is equivalent to the thread pool, no thread, that is to say at this time of the thread pool is not occupy any resource, So this thread pool is better suited for performing a large number of less time-consuming tasks
public static ExecutorService newCachedThreadPool() { returnnew ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } /* * Runnable r=newRunnable(){ @Override run() {... } } ExecutorService executor = Executors.newCachedThreadPool(); executor.execute(r)Copy the code
-
-
ScheduledThreadPool
-
The thread pool is created by using the Executors newCachedThreadPool() method. The number of core threads in the thread pool is fixed and the non-core thread data is unlimited, and the thread is immediately recycled when the non-core thread is idle. So we can use it to handle timed and repetitive tasks (similar to Task timeTasks)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { returnnew ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); } /* * Runnable r=newRunnable(){ @Override run() {... } } ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); / / 1000 ms after a mission executor. The schedule (r, 1000, TimeUnit. MICROSECONDS) / / 1000 ms delay every 1000 ms repeat task Executor. ScheduleAtFixedRate (r, 1000100, TimeUnit. MICROSECONDS)Copy the code
-
-
SingleThreadExector
- * If the thread is created by using Executors’ newCachedThreadPool() method, ensure that all tasks are executed sequentially in the same thread. * If the thread is created by Executors’ newCachedThreadPool(), ensure that all tasks are executed sequentially in the same thread.
public static ExecutorService newSingleThreadExecutor() { returnnew FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } / * * get usage * / ExecutorService executor. = Executors newSingleThreadExecutor (); executor.execute(r) Runnable r=newRunnable(){ @Override run() {... } } ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(r)Copy the code
-
-
From the introduction of the four Java thread pools above, we can see that ThreadPoolExecutor objects are ultimately created, which means that ThreadPoolExecutor is the core implementation of a thread pool.
-
ThreadPoolExecutor is one of the more common constructors
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } // corePoolSize: By default, the number of core threads will always exist, whether idle or not, but if the pool is set to the number of core threads, that is, allowCoreThreadTimeOut of ThreadPoolExecutor BooleantrueIf the number of core threads is zero, the value of allowCoreThreadTimeOut istrueThe timeout value is the keepAliveTime value, which is why all threads in the CachedThreadPool can be reclaimed. The number of core threads is zero, that is, there are no core threads. Non-core thread timeout if allowCoreThreadTimeOut istrue, the timeout value will be applied to the core of the idle thread unit: when the timeout time unit TimeUnit. MILLISECONDS/SECONDS/MINUTES/SECONDS/MINUTES (MILLISECONDS) workQueue: Thread task queue, which holds thread task threadFactory: // Create a new thread for the thread pool with defaultHandler, which is the RejectedExecutionHandler object: When a thread queue is full, the thread or task cannot execute thrown this parameter is used to inform RejectedExecutionException, here a constructor to temporarily doesn't workCopy the code
-
In Android, we can write our own thread management class. Let’s implement our own thread pool management class to manage our threads
/** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Created by ** * Public class ThreadManager {private static ThreadPool mThreadPool; public static ThreadPoolgetmThreadPool() {if (mThreadPool==null){ synchronized (ThreadManager.class){ if(mThreadPool==null){// mThreadPool=new ThreadPool(5,10,1L); }}}returnmThreadPool; } public static class ThreadPool{private int corePoolSize; Private int maximumPoolSize; Private long keepAliveTime; // Thread sleep time 1 second private ThreadPoolExecutor executor; private ThreadPool( int corePoolSize, int maximumPoolSize,long keepAliveTime){ this.corePoolSize=corePoolSize; this.maximumPoolSize=maximumPoolSize; this.keepAliveTime=keepAliveTime; } public void execute(Runnable Runnable){** * int corePoolSize * int maximumPoolSize, * Long keepAliveTime * TimeUnit unit * BlockingQueue<Runnable> workQueue Thread queue * ThreadFactory ThreadFactory, the factory for generating threads */if(executor==null){ executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy()); } / / core thread has timeout mechanism executor allowCoreThreadTimeOut (true); executor.execute(runnable); } public void cancelTask(Runnable Runnable){if(runnable! =null){ executor.getQueue().remove(runnable); }}}} / / using ThreadManager getmThreadPool (). The execute (newRunnable() { @Override public void run() {// Perform tasks}});Copy the code
-
Ok, that’s all I know about thread pools. If there are any mistakes, please leave me a comment and let’s learn and improve.
-
References:
- Exploring the Art of Android Development
- Ideas for Java Programming (4th edition)
- Synchronize abbreviated address