synchronisations-optimierung

Status
Nicht offen für weitere Antworten.
T

TangoFan

Gast
Mal ne generelle Frage zur Synchronisation. Habe folgendes Code-Konstrukt:

Code:
public class MeineKlasse {
...
private static ArrayList gemeinsameDatenstruktur = new ArrayList(); 

public void doGet(HttpServletRequest request, HttpServletResponse response)...
{
  ...
synchronized(this)
{
   ..tue etwas wichtiges..
   ..tue noch was wichtiges..

   AndereKlasse ak = new AndereKlasse();
   String wichtig = ak.andereMethode(etwasBerechnen);
 
   gemeinsameDatenstruktur.add(wichtig);    

}

Das Problem ist, ich will die Synchronisation optimieren. Habe ein Servlet welches die Requests entgegen nimmt. Hier können noch mehrere Threads darauf zugreifen. In dem synchronized-Block ist der Ablauf der Befehle dort drinnen fest vorgegeben, diese müssen synchronisiert hintereinander ablaufen da unter anderen in eine gemeinsame Datenstruktur ("gemeinsameDatenstruktur") geschrieben wird. Das einzige was ich nun "outsourcen" könnte wäre der Methodenaufruf von der Klasse "AndereKlasse". Diese "AndereKlasse" verarbeitet gleichzeitig mehrere Threads und hätte kein Problem wenn mehrere Threads dieselbe Funktion "andereMethode" aufrufen. Allerdings benötigt dieser Methodenaufruf einiges an Zeit.

Gibt es eine Möglichkeit den Methodenaufruf auszulagern damit dieser wenigstens wieder Thread-fähig wird?
 
S

SlaterB

Gast
die andere Klasse kann ja weiterhin von außen gerufen werden,
niemand verhindert dies,

ist der gepostete Code allerdings die einzige Stelle, an der die andere Klasse gerufen wird,
dann wird diese immer nur synchronisiert gerufen, das stimmt,

allerdings ist dies dann nicht die Schuld der anderen Klasse und auch kein unglückliches Konstrukt,
es ist einfach so,

stell dir vor eine Bank liest
A den Kontostand eines Kunden, berechnet B in einer öffentlichen Hilfsklasse die Zinsen, und schreibt C den Kontostand zurück,

dann kann man nicht einfach sagen dass die Zinsberechnung ohne synchronzised durchgeführt werden soll,
auch wenn dort normalerweise nix gemeinsames passiert,

wichtig ist nur, dass diese Berechnung Teil der Gesamttransaktion ist,
die Synchronisation von A nach C reicht, und B nunmal irgendwie dazu gehört,

-----------

ist bei dir aber eine andere Situation vorherrschend,
nämlich
> gemeinsameDatenstruktur.add(wichtig);
unabhängig von
> ..tue etwas wichtiges..
> ..tue noch was wichtiges..
(also darf inzwischen auch ein anderer Thread sowas wichtiges tun)

dann spricht nichts gegen

Code:
synchronized(this) 
{ 
   ..tue etwas wichtiges.. 
   ..tue noch was wichtiges.. 
}
   AndereKlasse ak = new AndereKlasse(); 
   String wichtig = ak.andereMethode(etwasBerechnen); 
synchronized(this) 
{ 
   gemeinsameDatenstruktur.add(wichtig);    

}
im Normalfall geht dies aber nicht,
du kannst höchstens überlegen, ob Teile der aufwendigen Operation in der anderen Klasse vielleicht schon vor dem ganzen Block gemacht werden können
(z.B. irgendwelche Konstanten nachschlagen)

denkbar wäre auch, erst die Werte zu lesen,
den Zugriff freizugeben, die andere Klassen berechnen zu lassen,
dann wieder Zugriff zu holen und die Ausgangwerte der Berechnung mit den aktuellen Werten zu vergleichen,
stimmen diese (noch) überein, dann würde also eine Berechnung im synchronized-Block das gleiche Ergebnis bringen,
ergo kann sofort mit diesem Ergebnis weitergearbeitet werden (Zeit im synchronized nun kürzer),
ansonsten muss nochmal neu berechnet werden
 
T

TangoFan

Gast
Vielen dank für deine ausführliche Erklärung. Ich muss mir das nun in ruhe durch den Kopf gehen lassen.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben