/ / Jak poznać tylko n liczbę wątków uruchomionych na sekundę przy użyciu RateLimiter - wielowątkowość, java.util.concurrent, ograniczenie prędkości

Jak poznać tylko n liczby wątków uruchomionych na sekundę za pomocą RateLimiter - wielowątkowość, java.util.concurrent, ograniczanie prędkości

Robię prostą implementację demonstracyjną, aby zrozumieć RateLimiter.

Zrobiłem prostą klasę, która pokazuje wiele wątków działających w ciągu sekundy.

Jeśli sprawdzasz dane wyjściowe, 2. sekunda, to pokazuje, że wątek-6 również zaczął się bez ukończenia wątku-2 i wątku-7.

Jeśli się mylę, pomóż mi, jak działa RateLimiter. Jakie zmiany muszę zrobić w klasie poniżej, aby zrozumieć zachowanie RateLimiter.

Mój kod jest następujący:

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

Wydajność:

-----------------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

Odpowiedzi:

0 dla odpowiedzi № 1

RateLimiter nakłada ograniczenia na RATE, a nie na liczbę zezwoleń. RateLimiter wydaje pozwolenia na określoną stawkę. Nigdy nie przestanie wydawać zezwoleń.

Pomyśl o tym w ten sposób: jeśli ustawisz szybkość 10 / s, to returnLimiter.acquire () zwróci co 100 ms (ponieważ 10 * 100 = 1000 ms). Możesz nazwać go 5000 razy, a on zwróci 5000 razy, po prostu zajmie 5000 * 100 = 50000 ms.

Zasadniczo wdrażasz ograniczenie szybkości tworzenia nowych wątków, a nie całkowitą liczbę wątków, które można utworzyć.

Przeczytaj dokumentację tutaj aby zobaczyć szczegóły. Pierwsze zdanie wyjaśnia zachowanie:

Ogranicznik prędkości. Koncepcyjnie ogranicznik prędkości dystrybuuje pozwolenia na konfigurowalna stawka. Każdy nabywa () blokuje, jeśli to konieczne, aż do uzyskania pozwolenia jest dostępny, a następnie bierze go. Po uzyskaniu pozwolenia nie muszą być wydany.

Następne zdanie dokumentacji API pokazuje, jak możesz ograniczyć całkowitą liczbę (w przeciwieństwie do stawki):

Ograniczniki prędkości są często stosowane w celu ograniczenia prędkości, z jaką niektóre dostęp do zasobów fizycznych lub logicznych. Jest to w przeciwieństwie do Semafor, który ogranicza liczbę równoczesnych dostępów zamiast Stawka (zauważ jednak, że współbieżność i stawka są ściśle powiązane, na przykład patrz Prawo Małego).

Nawiasem mówiąc, jeśli potrzebujesz stałej liczby wątków współpracujących nad czymś, zdecydowanie nie polecam tego z niestandardowym kodem. Zamiast tego spójrz na Executors i użyj newFixedThreadPool zamiast.