PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: einen Vector konsistent verarbeiten bei multiplen Threads


Ree
2012-02-19, 15:20:52
Hallo!

Tut mir leid für den komischen Titel, deshalb hier jetzt eine genauere Beschreibung:

Ich habe eine Klasse (Java), welche einen Vector kapselt. Die Klasse bietet Methoden an, um von außen Einträge in den Vector einfügen und auch wieder löschen zu können. Diese Methoden werden aus verschiedenen Threads heraus aufgerufen.
Das ist zwar nicht mein eigentliches Anliegen, aber hier die erste Frage: da der Vector per default thread-safe ist, muss ich die Methoden nicht auf multithreading auslegen (synchronzied etc), richtig?

Soweit, so gut. Worüber ich grüble:
Es gibt noch eine weitere Methode, die den Charakter von toString() besitzt. Diese nimmt den Vector, verarbeitet ihn in mehreren Schritten - sie extrahiert z.B. die letzten X Einträge aus dem Vector, wobei X (int) der Methode als Parameter übergeben wird. Das, was die Methode am Ende zurückgibt, ist ein formatierter String.

Ich bin mir nun unsicher, wie ich das ganze threadsafe gestalten kann.
Mit nur einem thread wäre es einfach:


public String getInfo(int x) {
int size = vector.size(); // danach noch prüfen, ob size >= x
for(int i = size; i > size-x; i--) {
// mit i-1 als index Daten aus Vector extrahieren und verarbeiten
stringbuilder.append(rechenergebnis);
}
return stringbuilder.tostring();
}


Bei mehreren Threads habe ich jetzt das Problem, dass z.B. "size" veraltet sein könnte, wenn die Schleife beginnt. Wenn der Vector gerade noch 16 Einträge hatte, dies in size abgespeichert wird, der Vector danach aber von einem anderen Thread geleert wird, dann krachts ja in der Schleife.

Jetzt will ich aber nicht um die komplette Verarbeitung ein synchronize machen, denn die Schleife läuft gut und gerne mal 5-10 Sekunden, dann würden in dieser Zeit ja alle fremden Zugriffsversuche blockiert werden.

Wie könnte ich das lösen?

kurz: Aus einem Vector sollen die letzten X Einträge ausgelesen werden, wobei andere Threads den Vector in der Zwischenzeit manipulieren können. Die ganze Operation zu synchronisieren wäre aber zu teuer, da die Schleife gerne mal 10 Sekunden läuft.

Vielen Dank!

Tiamat
2012-02-19, 17:08:34
Du könntest den synchronisierten Block darauf beschränken, die gewünschten Stellen zu extrahieren oder gar den Vector zu kopieren und danach deine Berechnung auszuführen.

Pinoccio
2012-02-19, 17:21:34
Wenn deine Schleife 5-10 ekudnen läuft, dein "VEctor" sich zwischenzeitlich ädnern kann, welches Ergebjis möchtest du dann eigentlich? Wenn du das Ergbenis vom Zeitpunkt des Funktionsaufrufs haben willst, dann ist Tiamats Vorschlag, erst threadsafe eine Kopie anzulegen und dann zu rechnen womöglich sinnvoll.
Ist natürlich schwierig, wenn deine verwalteten Objekte sehr viel Platz brauchen.

Was rechnest du denn?

mfg

Tiamat
2012-02-19, 17:25:03
Mich würde mal die Anwendung interessieren ^^

Gast
2012-02-19, 17:47:35
Danke schonmal

Du könntest den synchronisierten Block darauf beschränken, die gewünschten Stellen zu extrahieren oder gar den Vector zu kopieren und danach deine Berechnung auszuführen.

Eine bessere Idee hatte ich bisher auch nicht, aber werde es wohl so machen.

Wenn deine Schleife 5-10 ekudnen läuft, dein "VEctor" sich zwischenzeitlich ädnern kann, welches Ergebjis möchtest du dann eigentlich?

Das zum Zeitpunkt der Anfrage ist natürlich ausreichend :) Ohne Einschluss von Folgeänderungen

Mich würde mal die Anwendung interessieren ^^

Es ist eine Art flüchtiger Logger ohne Persistenz. Alle möglichen threads schreiben Meldungen hinein, aber irgendwie sollen sie natürlich auch angezeigt/ausgegeben werden können, falls gewünscht.
"Berechnen" war der falsche Ausdruck, es sind massig String-operationen, um das optisch in eine ansprechende Form zu bringen.



PS:
Wie heißt der Präsident der Bundesrepublik Deutschland?
hm, null?

ScottManDeath
2012-02-20, 09:49:21
Jeder thread bekommt seine eigene Log queue in die Messages mit timestamp und thread ID reingeschrieben werden. Ein weitere thread holt sich dann von diesen Threads die neuen Nachrichten (per Kopie) und formatiert sie dann wie gewollt.