Introduce the working characteristics of thread pool in Java with an example

  • 2020-04-01 04:08:23
  • OfStack

Why do we have to use thread pools?

Personally, I think the main reason is that there are a lot of tasks to deal with in a short time

Benefits of using thread pools:

1. Reduce the time spent creating and destroying threads and the overhead of system resources
2. If the thread pool is not used, it may cause the system to create a large number of threads, resulting in the consumption of system memory

Here are some of the thread pools that come with Java:

1, newFixedThreadPool  Creates a thread pool that specifies the number of worker threads.

A worker thread is created each time a task is committed, and if the number of worker threads reaches the maximum of the initial thread pool, the committed task is stored in the pool queue.

2. NewCachedThreadPool creates a cacheable thread pool.

This type of thread pool features:

1). There is almost no limit to the number of worker threads created (in fact, there is a limit to the number of Interger. MAX_VALUE), so you can add threads to the thread pool flexibly.

2). If a task is not submitted to the thread pool for a long time, that is, if the worker thread is idle for the specified time (the default is 1 minute), the worker thread will automatically terminate. After termination, if you commit a new task, the thread pool recreates a worker thread.

3. NewSingleThreadExecutor creates a single threaded Executor that only creates a single thread of workers to execute the task, and if that thread ends unexpectedly, another replaces it, ensuring sequential execution (which I think is its specialty).

The most important feature of a single worker thread is that it is guaranteed to execute each task sequentially and that no more than one thread is active at any given time.

4, newScheduleThreadPool  Creates a fixed-length thread pool and supports timed and periodic task execution, similar to a Timer.

Conclusion:

One.FixedThreadPool is a typical and excellent thread pool, it has the advantages of thread pool to improve program efficiency and save the cost of thread creation. However, when the thread pool is idle, that is, there are no runnable tasks in the thread pool, it will not release the worker thread and will occupy some system resources.

two The characteristic of CachedThreadPool is that when the thread pool is idle, that is, when there are no runnable tasks in the thread pool, it releases the worker thread, thus releasing the resources occupied by the worker thread. However, when a new task appears, a new worker thread is created, and there is some overhead. Also, when using CachedThreadPool, it is important to control the number of tasks, or else the system will crash due to the large number of threads running at the same time.

Java thread pool ThreadPoolExecutor USES instances


package com.sondon.mayi.jpool; 
 
import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 
 
public class JPoolLearn { 
 
 private static int produceTaskSleepTime = 3; 
 private static int produceTaskMaxNumber = 20; 
  
 public void testThreadPoolExecutor(){ 
  /* 
   * ThreadPoolExecutor( 
   * int corePoolSize, //A thread pool maintains a minimum number of threads
   * int maximumPoolSize, //A thread pool maintains a maximum number of threads
   * long keepAliveTime, //The thread pool maintains the free time allowed for threads
   * TimeUnit unit, //A thread pool maintains a unit of free time allowed by a thread
   * BlockingQueue<Runnable> workQueue, //The buffered queue used by the thread pool
   * RejectedExecutionHandler handler //Thread pool processing strategy for rejected tasks)
   */ 
  ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 
    5, 
    10, 
    3, 
    TimeUnit.SECONDS, 
    new ArrayBlockingQueue<Runnable>(10), 
    new ThreadPoolExecutor.DiscardOldestPolicy() 
    ); 
 
  for (int i = 1; i <= produceTaskMaxNumber; i++) { 
   try { 
    //Generates a task and adds it to the thread pool
    String task = "task---" + i; 
    threadPool.execute(new ThreadPoolTask(task)); 
    System.out.println("activeCount :"+ threadPool.getActiveCount()); 
    //Easy to observe, wait a while
    Thread.sleep(produceTaskSleepTime); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
  } 
   
  //View the current thread pool status
  while(true){ 
   try { 
    Thread.sleep(3000); 
    System.out.println("pool size :"+threadPool.getPoolSize());//The number of threads in the thread pool
    System.out.println("active count :"+threadPool.getActiveCount());//The number of threads active in the thread pool
   } catch (InterruptedException e) { 
    e.printStackTrace(); 
   } 
  } 
 } 
 
  
 public void testNewCachedThreadPool(){ 
  ThreadPoolExecutor threadPool=(ThreadPoolExecutor) Executors.newCachedThreadPool(); 
//  ThreadPoolExecutor threadPool=(ThreadPoolExecutor) Executors.newFixedThreadPool(100); 
//  ThreadPoolExecutor threadPool=(ThreadPoolExecutor) Executors.newScheduledThreadPool(100); 
//  ThreadPoolExecutor threadPool=(ThreadPoolExecutor) Executors.newSingleThreadExecutor(); 
  try { 
  for (int i = 0; i < 100; i++) { 
   //Generates a task and adds it to the thread pool
   String task = "task---" + i; 
   threadPool.execute(new ThreadPoolTask(task)); 
   System.out.println("activeCount :"); 
   //Easy to observe, wait a while
   Thread.sleep(produceTaskSleepTime); 
    
   } 
  } catch (InterruptedException e) { 
   e.printStackTrace(); 
  } 
  //View the current thread pool status
  while(true){ 
   try { 
    Thread.sleep(3000); 
    System.out.println("pool size :"+threadPool.getPoolSize());//The number of threads in the thread pool
    System.out.println("active count :"+threadPool.getActiveCount());//The number of threads active in the thread pool
   } catch (InterruptedException e) { 
    e.printStackTrace(); 
   } 
  } 
 } 
  
  
 public void testNewCachedThreadPool_callable(){ 
  ExecutorService es=Executors.newFixedThreadPool(10); 
  try { 
    
//   String result=es.submit(new MyCallable<String>()).get(); 
//   System.out.println("callable result :"+result); 
    
   String result=(String) es.submit(new ThreadPoolTask("")).get(); 
   System.out.println("runable result :"+result); 
    
  } catch (InterruptedException | ExecutionException e) { 
   e.printStackTrace(); 
  } 
 } 
  
  
 public static void main(String[] args) { 
  new JPoolLearn().testNewCachedThreadPool(); 
 } 
} 
 
 
 
 
class ThreadPoolTask implements Runnable { 
 private static int consumeTaskSleepTime = 2000; 
 //Save the data needed for the task
 private Object threadPoolTaskData; 
 
 ThreadPoolTask(Object tasks) { 
  this.threadPoolTaskData = tasks; 
 } 
 
 public void run() { 
  System.out.println("start .." + threadPoolTaskData); 
  try { 
   //Sleep 2 second simulation time operation
   Thread.sleep(consumeTaskSleepTime); 
  } catch (Exception e) { 
   e.printStackTrace(); 
  } 
  threadPoolTaskData = null; 
 } 
 
 public Object getTask() { 
  return this.threadPoolTaskData; 
 } 
} 
 
 
class MyCallable<T> implements Callable<T>{ 
  
 @Override 
 public T call() throws Exception { 
   System.out.println(" Start to perform Callable"); 
   return (T) " test callable interface "; 
  } 
} 


Related articles: