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.
Use ExecutorService to limit the maximum number of threads.
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.
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()));
}
}
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();
}
}
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
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.
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.
https://github.com/nogitsune413/ExecutorServiceSample
Java8 API Specification ExecutorService How to use ExecutorService Stop running Thread.start (). "ExecutorService" makes thread management easy. Multithreading in Java using ExecutorService
Java 1.8
Recommended Posts