Limiter le nombre de threads à l'aide du service d'exécution de Java

problème

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.

Solution

Utilisez ExecutorService pour limiter le nombre maximum de threads.

Qu'est-ce que le service exécuteur

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.

Créer un programme de test

fil

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()));
	}
}

ExecutorService avec pool de threads

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();
	}
}

Réalisation du test

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

Analyse des résultats des tests

Nombre maximum de threads

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.

L'appelant ExecutorService n'est pas bloqué

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.

Exemple de code

https://github.com/nogitsune413/ExecutorServiceSample

référence

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

Environnement de confirmation

Java 1.8

Recommended Posts

Limiter le nombre de threads à l'aide du service d'exécution de Java
À propos du nombre de threads de Completable Future
Lorsque vous utilisez le constructeur de la classe Date de Java, la date avance de 1900.
Commande pour vérifier le nombre et l'état des threads Java
J'ai essayé d'utiliser la fonction de cache d'Application Container Cloud Service
Essayez d'utiliser || au lieu de l'opérateur ternaire
Essayez d'utiliser le service sur Android Oreo
Comment déterminer le nombre de parallèles
[Java] Vérifiez le nombre d'occurrences de caractères
Vérifiez le fonctionnement de l'interface à travers le thread
[Rails] Mise en œuvre du classement des nombres PV à l'aide de l'impressionniste
J'ai essayé d'utiliser le profileur d'IntelliJ IDEA
J'ai vérifié le nombre de taxis avec Ruby
[Rails] Utilisez la zone déroulante pour trier la liste des articles par date ou par nombre de likes.
Implémentons une fonction pour limiter le nombre d'accès à l'API avec SpringBoot + Redis
Être un peu bloqué le dernier jour du mois en utilisant la classe Calendar de Java