Four Java thread pool usage resolutions

  • 2020-05-07 19:52:24
  • OfStack

This article analyzes four types of Java thread pool usage for your reference, the specific content is as follows

1, new Thread disadvantages

Do you still perform an asynchronous task as new Thread?


new Thread(new Runnable() {

  @Override
  public void run() {
    // TODO Auto-generated method stub
    }
  }
).start();

Then you have too many out. The disadvantages of new Thread are as follows:

a. Poor performance every time new Thread is created.
b. Threads lack unified 1 management, may create unlimited threads, compete with each other, and may take up too much system resources resulting in crashes or oom.
c. Lack of more functions, such as timed execution, periodic execution, thread interruption.

Compared to new Thread, Java provides four thread pools with the following benefits:

a. Reuse existing threads, reduce the overhead of object creation and death, good performance.
b. Can effectively control the maximum number of concurrent threads, improve the utilization of system resources, and avoid excessive resource competition, avoid congestion.
c. Provides timed execution, scheduled execution, single thread, concurrency control and other functions.

2, Java thread pool

Java provides four thread pools through Executors, which are:

newCachedThreadPool creates a cacheable thread pool. If the thread pool length exceeds the processing requirement, the idle thread can be recycled flexibly. If there is no recycling, a new thread can be created.
newFixedThreadPool creates a fixed-length thread pool, which controls the maximum number of concurrent threads, and the exceeded threads will wait in the queue.
newScheduledThreadPool creates a fixed-length thread pool to support timed and periodic task execution.
newSingleThreadExecutor creates a single threaded thread pool that executes tasks with only 1 worker thread, ensuring that all tasks execute in the specified order (FIFO, LIFO, priority).
(1) newCachedThreadPool:

Create a cacheable thread pool, if the thread pool length exceeds the processing needs, the free thread can be recycled flexibly, if there is no recycling, new thread. The sample code is as follows:


ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  for (int i = 0; i < 10; i++) {
    final int index = i;
  try {
    Thread.sleep(index * 1000);
  } 
    catch (InterruptedException e) {
      e.printStackTrace();
  }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
  System.out.println(index);
}
});
}

The thread pool is infinite, when the second task is executed, the first task is completed, the thread executing the first task will be reused, instead of each new thread.

(2) newFixedThreadPool:

Create a fixed-length thread pool to control the maximum number of concurrent threads. The sample code is as follows:


ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
  for (int i = 0; i < 10; i++) {
  final int index = i;

  fixedThreadPool.execute(new Runnable() {

@Override
public void run() {
try {
  System.out.println(index);
  Thread.sleep(2000);
} catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
}
});
}

Because the thread pool size is 3, each task outputs index 2 seconds after sleep, so three Numbers are printed every two seconds.

The size of the fixed-length thread pool is best set based on system resources. Such as Runtime. getRuntime (.) availableProcessors (). See PreloadDataCache.

(3) newScheduledThreadPool:

Create a fixed - length thread pool, support timing and periodic task execution. The delay execution sample code is as follows:


ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
 scheduledThreadPool.schedule(new Runnable() {

@Override
public void run() {
  System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

Represents a delay of 3 seconds.

Periodically execute the sample code as follows:


scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override
public void run() {
  System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);

Means that the delay of 1 second is executed every 3 seconds.

ScheduledExecutorService is safer and more powerful than Timer

(4) newSingleThreadExecutor:

Create a single threaded thread pool that will execute tasks with only 1 worker thread, ensuring that all tasks execute in the specified order (FIFO, LIFO, priority). The sample code is as follows:


ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {

@Override
public void run() {
  try {
    System.out.println(index);
  Thread.sleep(2000);
} catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
    }
}
  });
}

The results are output in turn, which is equivalent to executing each task in sequence.

Most current GUI programs are single-threaded. Single thread in Android can be used for database operation, file operation, application batch installation, application batch deletion, etc., which is not suitable for concurrent operation, but may block IO and affect the response of UI thread.

What thread pool does:

The purpose of the thread pool is to limit the number of execution threads in the system.
According to the environment of the system, the number of threads can be set automatically or manually to achieve the best effect. Less wasted system resources, more resulting in system congestion efficiency is not high. Use the thread pool to control the number of threads, with other threads lining up to wait. After 1 task is completed, the first task in the queue is selected to execute. If there is no waiting process in the queue, this 1 resource of the thread pool is waiting. When a new task needs to run, if there is a waiting worker thread in the thread pool, it can start running. Otherwise enter the wait queue.

Why do use thread pools:

1. Reduces the number of threads created and destroyed, so that each worker thread can be reused to perform multiple tasks.

2. The number of threads in the thread pool can be adjusted according to the system's capacity, so as to prevent the server from being exhausted due to excessive memory consumption (each thread needs about 1MB memory, the more threads open, the more memory consumption, and the final crash).

The top-level interface to the thread pool in Java is Executor, but Executor is not strictly a thread pool, just a tool for executing threads. The real thread pool interface is ExecutorService.

A few of 's more important classes:

ExecutorService: true thread pool interface.

ScheduledExecutorService: similar to Timer/TimerTask, ScheduledExecutorService solves problems that require repetitive tasks.

ThreadPoolExecutor: the default implementation of ExecutorService.

ScheduledThreadPoolExecutor: ScheduledExecutorService interface implementation inherited from ThreadPoolExecutor, class implementation of periodic task scheduling.

It is complicated to configure a thread pool, especially if the principle of thread pool is not very clear, it is likely that the configured thread pool is not superior, so some static factories are provided in Executors class to generate some commonly used thread pools.

1.newSingleThreadExecutor

Create a single thread pool. This thread pool has only one thread working, which is the equivalent of a single thread executing all tasks sequentially. If the one-only thread ends because of an exception, a new thread replaces it. This thread pool ensures that all tasks are executed in the order in which they were submitted.

2.newFixedThreadPool

Create a fixed-size thread pool. One thread is created each time a task is submitted until the thread reaches the maximum size of the thread pool. The size of the thread pool remains the same once it reaches its maximum, and if a thread ends because of an exception, a new thread is added to the pool.

3.newCachedThreadPool

Create a cacheable thread pool. If the thread pool size exceeds the number of threads needed to process the task,

Some idle threads (60 seconds without executing a task) are recycled, and as the number of tasks increases, the thread pool can intelligently add new threads to handle the task. There is no limit to the size of the thread pool, which is completely dependent on the maximum thread size that the operating system (or JVM) can create.

4.newScheduledThreadPool

Create a thread pool of infinite size. This thread pool supports the need for timed and periodic execution of tasks.

The sample code

1. Fixed-size thread pool, newFixedThreadPool:


package app.executors; 

import java.util.concurrent.Executors; 
import java.util.concurrent.ExecutorService; 

/** 
 * Java Threads: thread pool  
 * 
 * @author xiho
 */ 
public class Test { 
  public static void main(String[] args) { 
    //  create 1 A pool of reusable threads with a fixed number of threads  
    ExecutorService pool = Executors.newFixedThreadPool(2); 
    //  Create a thread  
    Thread t1 = new MyThread(); 
    Thread t2 = new MyThread(); 
    Thread t3 = new MyThread(); 
    Thread t4 = new MyThread(); 
    Thread t5 = new MyThread(); 
    //  Put the thread into the pool for execution  
    pool.execute(t1); 
    pool.execute(t2); 
    pool.execute(t3); 
    pool.execute(t4); 
    pool.execute(t5); 
    //  Turn off the thread pool  
    pool.shutdown(); 
  } 
} 

class MyThread extends Thread { 
  @Override 
  public void run() { 
    System.out.println(Thread.currentThread().getName() + " Be executing... "); 
  } 
}

Output results:


pool-1-thread-1 Be executing...  
pool-1-thread-3 Be executing...  
pool-1-thread-4 Be executing...  
pool-1-thread-2 Be executing...  
pool-1-thread-5 Be executing... 

Change the parameters in ExecutorService pool = Executors.newFixedThreadPool (5) : ExecutorService pool = Executors.newFixedThreadPool (2), the output is:


pool-1-thread-1 Be executing...  
pool-1-thread-1 Be executing...  
pool-1-thread-2 Be executing...  
pool-1-thread-1 Be executing...  
pool-1-thread-2 Be executing... 

As you can see from the above results, the newFixedThreadPool parameter specifies the maximum number of threads that can be run, and any more than that will not run. Second, the threads that join the thread pool are in managed state, and the threads run regardless of the join order.

2. Single-task thread pool, newSingleThreadExecutor:

Just change ExecutorService pool = Executors.newFixedThreadPool (2) to ExecutorService pool = Executors.newSingleThreadExecutor ();
Output results:


pool-1-thread-1 Be executing...  
pool-1-thread-1 Be executing...  
pool-1-thread-1 Be executing...  
pool-1-thread-1 Be executing...  
pool-1-thread-1 Be executing... 

As you can see, every time you call execute, you end up calling run of thread-1.

Variable size thread pool, newCachedThreadPool:

pool = Executors. newCachedThreadPool(); ExecutorService pool = Executors. newCachedThreadPool();

Output results:


ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  for (int i = 0; i < 10; i++) {
    final int index = i;
  try {
    Thread.sleep(index * 1000);
  } 
    catch (InterruptedException e) {
      e.printStackTrace();
  }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
  System.out.println(index);
}
});
}

0

This approach has the advantage of creating a pool of new threads as needed, but reusing previously constructed threads when they are available.

Delayed connection pooling, newScheduledThreadPool:


ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  for (int i = 0; i < 10; i++) {
    final int index = i;
  try {
    Thread.sleep(index * 1000);
  } 
    catch (InterruptedException e) {
      e.printStackTrace();
  }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
  System.out.println(index);
}
});
}

1

Output results:


ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  for (int i = 0; i < 10; i++) {
    final int index = i;
  try {
    Thread.sleep(index * 1000);
  } 
    catch (InterruptedException e) {
      e.printStackTrace();
  }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
  System.out.println(index);
}
});
}

2

The above is the entire content of this article, I hope to help you with your study.


Related articles: