Limit the number of threads using Java's Executor Service

problem

I created a Java program in which multiple threads access the DB in parallel. However, it turned out that when the number of threads increased, the upper limit of the DB connection set in the DBMS was exceeded and the program freezes.

solution

Use ExecutorService to limit the maximum number of threads.

What is Executor Service

ExecutorService is an interface included in the Java standard parallel processing library "java.util.concurrent" package that wraps Java threads that are difficult to use raw and makes them easy to use.

■ ExecutorService --Standard API --Java 1.5 and above --java.util.concurrent package

For details, refer to Java 8 API Specification ExecutorService.

Creating a test program

thread

First, write just a thread. The actual processing is not done, but since it seems that the processing is taking a long time, sleep for the time given by the argument and then quit.

SampleThread.java


package sample;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class SampleThread implements Runnable {
	
	private int no;
	private int time;
	
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
	
	SampleThread(int no, int time) {
		this.no = no;
		this.time = time;
	}

	@Override
	public void run() {
		System.out.println(" No." + no + " start  id:" + Thread.currentThread().getId() + "Survival time:" + time + "Current time:" + sdf.format(Calendar.getInstance().getTime()));
		try {
			//Put it to sleep to make it appear that something is happening.
			Thread.sleep(time * 1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(" No." + no + " end    id:" + Thread.currentThread().getId() + "Survival time:" + time + "Current time:" + sdf.format(Calendar.getInstance().getTime()));
	}
}

ExecutorService with thread pool

Next, use ExecutorService and try using the thread I wrote earlier. Since ExecutorService is an interface, we need to implement this interface, but here we can use the Executors # newFixedThreadPool method to get an ExecutorService with a thread pool. The upper limit of the thread pool is set to 3 threads for the sake of clarity.

Main.java


package sample;

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

public class Main {

	public static void main(String[] args) {
		
		//Set the maximum thread pool value to 3 threads.
		final int MAX_THREADS = 3;
		
		//Create an ExecutorService with a thread pool using the factory method "newFixedThreadPool".
		ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);

		//Try to set up 10 threads
		for (int i = 0; i < 10; i++) {
			
			//Number the threads.
			int no = i;
			
			//Randomly determine thread survival time from 1 to 10 seconds.
			int lifeTime = (int)(Math.random() * 9 + 1);
			
			//Start a thread.
			executor.submit(new SampleThread(no, lifeTime));
		}
		//Close ExecutorService.
		System.out.println("executor.shutdown();");
		executor.shutdown();
	}
}

Conducting the test

When the above test program is run, the following is output to the console.

item meaning
No. Processing number given as an argument when starting a thread
id Thread-specific id.
Survival time The amount of time the thread is sleeping. (Seconds)

console


 No.0 start  id:12 survival time:1 Current time:13:29:41
 No.1 start  id:13 Survival time:8 Current time:13:29:41
 No.2 start  id:14 Survival time:6 Current time:13:29:41
executor.shutdown();
 No.0 end    id:12 survival time:1 Current time:13:29:42
 No.3 start  id:12 survival time:1 Current time:13:29:42
 No.3 end    id:12 survival time:1 Current time:13:29:43
 No.4 start  id:12 survival time:9 Current time:13:29:43
 No.2 end    id:14 Survival time:6 Current time:13:29:47
 No.5 start  id:14 Survival time:2 Current time:13:29:47
 No.1 end    id:13 Survival time:8 Current time:13:29:49
 No.6 start  id:13 Survival time:9 Current time:13:29:49
 No.5 end    id:14 Survival time:2 Current time:13:29:49
 No.7 start  id:14 Survival time:7 Current time:13:29:49
 No.4 end    id:12 survival time:9 Current time:13:29:52
 No.8 start  id:12 survival time:7 Current time:13:29:52
 No.7 end    id:14 Survival time:7 Current time:13:29:56
 No.9 start  id:14 Survival time:4 Current time:13:29:56
 No.6 end    id:13 Survival time:9 Current time:13:29:58
 No.8 end    id:12 survival time:7 Current time:13:29:59
 No.9 end    id:14 Survival time:4 Current time:13:30:00

Analysis of test results

Maximum number of threads limit

Looking at the "No." part, there are numbers from 0 to 9, and the thread is processed 10 times. On the other hand, if you look at the thread ids, you can see that there are only 12 to 14, and the number of threads is limited to 3. Also, when the processing of one thread is completed, it can be confirmed that the thread with the same id is used in the next processing. From these things, it can be said that three threads are being reused. You can also see that the maximum number of threads running at the same time is 3.

ExecutorService callers are not blocked

The executor # shutdown method is called immediately after the maximum number of 3 threads is started. This is because when the thread reaches the maximum number of thread pools, the submit of the thread invocation source is not blocked, but the task itself is accepted by the FIFO Queue. You can also confirm that this Queue is working properly.

Sample code

https://github.com/nogitsune413/ExecutorServiceSample

reference

Java8 API Specification ExecutorService How to use ExecutorService Stop running Thread.start (). "ExecutorService" makes thread management easy. Multithreading in Java using ExecutorService

Confirmation environment

Java 1.8

Recommended Posts

Limit the number of threads using Java's Executor Service
About the number of threads of Completable Future
When using the constructor of Java's Date class, the date advances by 1900.
Command to check the number and status of Java threads
I tried using the cache function of Application Container Cloud Service
Try using || instead of the ternary operator
Try using the service on Android Oreo
Test the integrity of the aggregation using ArchUnit ②
How to determine the number of parallels
[Java] Check the number of occurrences of characters
Check the operation of the interface through threads
Test the integrity of the aggregation using ArchUnit ③
[Rails] Implementation of PV number ranking using impressionist
I tried using the profiler of IntelliJ IDEA
I checked the number of taxis with Ruby
[Rails] Sort the post list by date or number of likes using the pull-down box
Let's implement a function to limit the number of access to the API with SpringBoot + Redis
Getting a little stuck on the last day of the month using Java's Calendar class