Java Variable anzahl an Threads kontrollieren

gaunt

Lt. Commander
Registriert
Aug. 2007
Beiträge
2.014
Hi
ich hab mal wieder en Problemchen;-)

Ich habe einen Haufen Abfragen (REST Abfragen) die erledigt werden müssen. Außerdem habe ich einige wenige Accounts welche für die Abfrage benötigt werden. Jede Abfrage braucht einen Account und kein Account darf zweimal gleichzeitig verwendet werden. Es sind also maximal soviele parallele Threads möglich wie es Accounts gibt.

Sequentiell kein Ding:
Eine Client Klasse übernimmt die Abarbeitung. Bei der initialisierung bekommt der Konstruktor einen Task und einen Account übergeben und legt los. Im Prinzip werden einfach Tasks und Accounts hochgezählt und im Round Robin vergeben. Nur so eben nach einander.

Jetzt kann ich hingehen und einfach statt nur ein verarbeitendes Objekt zu erzeugen, eines in einem eigenen Thread starten. Klappt ja auch, aber nur mit sovielen Tasks wie ich Accounts habe. Ansonsten starten einfach alle Tasks fast gleichzeitig (die restliche Verarbeitung nimmt kaum Zeit in Anspruch), und dass logischerweise zumindest teilweise mit dem selben Account.

Im Prinzip müsste ich vorab soviele Therads erzeugen wie ich Accounts habe. Geht aber nicht, weil ich den Thread mit einem entprechenden Objekt erzeugen muss. Oder ich gucke in einer Endlosschleife wie weit die Tasks sind. Nur wie soll ich die in der Schleife auseinander halten (hab keine Ahnung von Threads!)? Ich müsste ja schauen mit welchem Account eben jener Thread gerade arbeitet...

Irgendwie hab ich nen Hirnknoten!
Hat nicht mal einer nen kleinen Tipp?
 
Ich würde einen ThreadPoolExecutor für die Ausführung verwenden. Damit kannst du dynamisch die maximal sinnvolle Anzahl an Threads verwenden.
Damit keine Account Kollisionen entstehen kannst du für für jeden Account zu dem eine Anfrage existiert einen Task anlegen, der alle Tasks zugeordnet kriegt:
Code:
Map<Account, List<Task>> accountTasks = restTasks.stream().collect(Collectors.toMap(
        Task::getAccount, 
        task -> Collections.singletonList(task),
        (l, t) -> l.addAll(t)));
accountTasks.valueSet().stream().forEach(
        taskList -> executor.execute(new ListRunnable(taskList)));

Den ListRunnable musst du dann so schreiben, dass er eine Liste von IRunnables erhält und die sequentiell ausführt.
 
Zuletzt bearbeitet:
Zurück
Oben