/ / Comment ne connaître que n nombre de threads exécutés par seconde à l'aide de RateLimiter - multithreading, java.util.concurrent, limitation de débit

Comment connaître uniquement n nombre de threads exécutés par seconde avec RateLimiter - multithreading, java.util.concurrent, limitant le débit

Je fais une simple implémentation de démonstration pour comprendre RateLimiter.

J'ai fait un cours simple, il montre plusieurs threads en cours d'exécution en une seconde.

Si vous archivez la sortie, 2nd Second, il montre que thread-6 a également démarré sans l'achèvement de thread-2 et Thread-7.

Si je me trompe, aidez-moi au fonctionnement de RateLimiter. Quels changements je dois faire dans la classe ci-dessous pour comprendre le comportement de RateLimiter.

Mon code est le suivant:

import java.util.Arrays;
import java.util.List;

import com.google.common.util.concurrent.RateLimiter;

public class RLClient2 {
public static void main(String[] args) {
RateLimiter rateLimiter = RateLimiter.create(2);
DT dt = new DT();
dt.setDaemon(true);
dt.start();
T t[] = new T[15];
for (int i = 0; i < t.length; i++) {
t[i] = new  T(rateLimiter);
t[i].start();
}
}
}

class T extends Thread {
RateLimiter rateLimiter = null;

T(RateLimiter rateLimiter) {
this.rateLimiter = rateLimiter;
}

@Override
public void run() {
rateLimiter.acquire();
for (int i = 0; i < 12; i++) {
try {
sleep(100);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
System.out.println(Thread.currentThread().getName() + " Completed..........");
}
}


class DT extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("-----------------" + i + " Seconds...");
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Sortie:

-----------------0 Seconds...
Thread-2
Thread-2
Thread-2
Thread-2
Thread-2
Thread-7
Thread-2
Thread-7
Thread-2
Thread-7
Thread-2
Thread-7
Thread-2
Thread-7
-----------------1 Seconds...
Thread-2
Thread-6
Thread-7
Thread-2
Thread-6
Thread-7
Thread-2
Thread-2 Completed..........
Thread-7
Thread-6
Thread-6
Thread-7
Thread-7
Thread-6
Thread-5
Thread-6
Thread-7
Thread-5
Thread-7
Thread-7 Completed..........
Thread-6
Thread-5
Thread-6
Thread-5
Thread-6
Thread-6
Thread-5
-----------------2 Seconds...
Thread-6
Thread-4
Thread-5
Thread-6
Thread-6 Completed..........
Thread-5
Thread-4
Thread-5
Thread-4
Thread-4

Réponses:

0 pour la réponse № 1

Le RateLimiter impose des restrictions sur le TAUX et non sur le nombre de permis. Un RateLimiter délivre des permis à un taux spécifique. Il n'arrêtera jamais de délivrer des permis.

Pensez-y comme ceci:si vous définissez un taux de 10 / s, alors rateLimiter.acquire () retournera toutes les 100 ms (car 10 * 100 = 1000 ms). Vous pouvez l'appeler 5000 fois et il reviendra 5000 fois, il faudra juste 5000 * 100 = 50000ms pour revenir.

Donc, essentiellement, vous implémentez une limite sur la vitesse à laquelle les nouveaux threads sont créés, et non sur le nombre total de threads qui peuvent être créés.

Lisez la documentation ici pour voir les détails. La toute première phrase explique le comportement:

Un limiteur de débit.Conceptuellement, un limiteur de débit distribue les permis à un taux configurable. Chaque acquisition () bloque si nécessaire jusqu'à l'obtention d'un permis est disponible, puis le prend. Une fois acquis, les permis ne doivent pas être publié.

La phrase suivante de la documentation de l'API révèle comment vous pouvez limiter le nombre total (par opposition au taux):

Les limiteurs de débit sont souvent utilisés pour limiter le taux auquel certains une ressource physique ou logique est accédée. Ceci est en contraste avec Sémaphore qui limite le nombre d'accès simultanés au lieu de Le taux (notez cependant que la concurrence et le taux sont étroitement liés, par exemple. voir Little "s Law).

À propos, si vous avez besoin d'un nombre fixe de threads collaborant sur quelque chose, je vous recommande vivement de ne pas le faire avec du code personnalisé. Jetez plutôt un œil aux exécuteurs et utilisez newFixedThreadPool au lieu.