J'ai créé un programme Java dans lequel plusieurs threads accèdent à la base de données en parallèle. Cependant, il s'est avéré que lorsque le nombre de threads augmentait, la limite supérieure de la connexion à la base de données définie par le SGBD était dépassée et le programme se fige.
Utilisez ExecutorService pour limiter le nombre maximum de threads.
ExecutorService est une interface incluse dans le package de la bibliothèque de traitement parallèle standard Java "java.util.concurrent" qui encapsule les threads Java difficiles à utiliser bruts et les rend faciles à utiliser.
■ ExecutorService
Pour plus de détails, reportez-vous à Java 8 API Specification ExecutorService.
Tout d'abord, écrivez simplement un fil. Le traitement proprement dit n'est pas terminé, mais pour donner l'impression que le traitement prend beaucoup de temps, dormez pendant le temps donné par l'argument puis quittez.
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() + "Temps de survie:" + time + "Heure actuelle:" + sdf.format(Calendar.getInstance().getTime()));
try {
//Mettez-le en sommeil pour faire semblant que quelque chose se passe.
Thread.sleep(time * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" No." + no + " end id:" + Thread.currentThread().getId() + "Temps de survie:" + time + "Heure actuelle:" + sdf.format(Calendar.getInstance().getTime()));
}
}
Ensuite, utilisez ExecutorService et essayez d'utiliser le fil que j'ai écrit plus tôt. Puisque ExecutorService est une interface, nous devons implémenter cette interface, mais ici nous pouvons utiliser la méthode Executors # newFixedThreadPool pour obtenir un ExecutorService avec un pool de threads. La limite supérieure du pool de threads est fixée à 3 threads par souci de clarté.
Main.java
package sample;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
//Définissez le pool de threads maximum sur 3 threads.
final int MAX_THREADS = 3;
//Créez un ExecutorService avec un pool de threads à l'aide de la méthode de fabrique "newFixedThreadPool".
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
//Essayez de configurer 10 threads
for (int i = 0; i < 10; i++) {
//Numérotez les fils.
int no = i;
//Le temps de survie du thread est déterminé aléatoirement entre 1 et 10 secondes.
int lifeTime = (int)(Math.random() * 9 + 1);
//Démarrez un fil.
executor.submit(new SampleThread(no, lifeTime));
}
//Fermez ExecutorService.
System.out.println("executor.shutdown();");
executor.shutdown();
}
}
Lorsque le programme de test ci-dessus est exécuté, les informations suivantes sont envoyées à la console.
article | sens |
---|---|
No. | Numéro de traitement donné en argument lors du démarrage d'un thread |
id | Identifiant spécifique au thread. |
Temps de survie | Durée pendant laquelle le thread est en veille. (Secondes) |
console
No.0 start id:12 temps de survie:1 Heure actuelle:13:29:41
No.1 start id:13 Temps de survie:8 Heure actuelle:13:29:41
No.2 start id:14 Temps de survie:6 Heure actuelle:13:29:41
executor.shutdown();
No.0 end id:12 temps de survie:1 Heure actuelle:13:29:42
No.3 start id:12 temps de survie:1 Heure actuelle:13:29:42
No.3 end id:12 temps de survie:1 Heure actuelle:13:29:43
No.4 start id:12 temps de survie:9 Heure actuelle:13:29:43
No.2 end id:14 Temps de survie:6 Heure actuelle:13:29:47
No.5 start id:14 Temps de survie:2 Heure actuelle:13:29:47
No.1 end id:13 Temps de survie:8 Heure actuelle:13:29:49
No.6 start id:13 Temps de survie:9 Heure actuelle:13:29:49
No.5 end id:14 Temps de survie:2 Heure actuelle:13:29:49
No.7 start id:14 Temps de survie:7 Heure actuelle:13:29:49
No.4 end id:12 temps de survie:9 Heure actuelle:13:29:52
No.8 start id:12 temps de survie:7 Heure actuelle:13:29:52
No.7 end id:14 Temps de survie:7 Heure actuelle:13:29:56
No.9 start id:14 Temps de survie:4 Heure actuelle:13:29:56
No.6 end id:13 Temps de survie:9 Heure actuelle:13:29:58
No.8 end id:12 temps de survie:7 Heure actuelle:13:29:59
No.9 end id:14 Temps de survie:4 Heure actuelle:13:30:00
En regardant la partie "Non", il y a des nombres de 0 à 9, et le fil est traité 10 fois. Par contre, si vous regardez l'id du thread, vous pouvez voir qu'il n'y en a que 12 à 14 et que le nombre de threads est limité à 3. En outre, lorsque le traitement d'un thread est terminé, il peut être confirmé que le thread avec le même identifiant est utilisé dans le traitement suivant. De ces choses, on peut dire que trois threads sont réutilisés. Vous pouvez également voir que le nombre maximum de threads en cours d'exécution en même temps est de 3.
La méthode exécutable # shutdown est appelée immédiatement après le démarrage du nombre maximum de 3 threads. En effet, lorsque le thread a atteint le nombre maximal de pools de threads, la soumission de la source d'appel du thread n'est pas bloquée, mais la tâche entière elle-même est acceptée par la file d'attente FIFO. Vous pouvez également confirmer que cette file d'attente fonctionne correctement.
https://github.com/nogitsune413/ExecutorServiceSample
Java8 API Specification ExecutorService Comment utiliser ExecutorService Arrêtez d'exécuter Thread.start (). "ExecutorService" facilite la gestion des threads. Traitement multithread en Java avec ExecutorService
Java 1.8
Recommended Posts