Synchronized - auf welchem Objekt

R

redbomber

Bekanntes Mitglied
Hi zusammen,

ich habe eine Frage:
Ich besitze eine statische Klasse die ein Array von DateFormat Objekten anbietet. Dieser Klasse kann ein String übergeben werden, welcher in ein Date formatiert wird.
Da DateFormat nicht threadSafe ist, habe ich den Block wo der String geparsed wird synchronisiert.

An dem folgendem Code könnt ihr sehen wie ich synchronisiere. Könnt ihr mir erklären warum Variante 1 nicht funktioniert. Variante 2 sollte funktionieren, aber nich nicht ausreichend getestet.

Java:
class MyClass{
	static DateFormat[] formats[]={...}
	
	//variante 1 
	static Date parse(String aDate){
		Date date;
		for(int i=0; i< formats.length; i++){
			synchronized(MyClass.class){
				date = formats[i].parse(aDate);
			}
			
			if(date!=null){
				return date;
			}
		}
		return date;
	}
	
	//variante 2 
	static Date parse(String aDate){
		Date date;
		for(int i=0; i< formats.length; i++){
			synchronized(formats[i]){
				date = formats[i].parse(aDate);
			}
			
			if(date!=null){
				return date;
			}
		}
		return date;
	}
}
 
Zuletzt bearbeitet:
S

SlaterB

Gast
was gibt es da zu erklären, das hat nichts mit Synchronisierung oder DateFormat zu tun,
in einer statischen Methode gibt es kein this, fertig?

oder erhälst du nicht bereits einen Compilerfehler? sondern stattdessen was anderes, läuft das Programm, funktioniert nur der gegenseitige Ausschluss nicht?
ausführliche Informationen, die Welt wäre so dankbar..
 
Zuletzt bearbeitet von einem Moderator:
nrg

nrg

Top Contributor
aber auch wenn die klasse nicht-statisch wäre, könne man über this nicht syncen. this bezieht sieht auf das aktuelle objekt und ist in jeder instanz logischerweiße unterschiedlich.
 
M

Michael...

Top Contributor
Mal abgesehen davon, dass ich den Sinn hinter der Synchronisation nicht verstehe, gibt es im statischen Kontext kein this, daher lässt sich Variante 1 nicht kompilieren.

Wozu das synchronized?
 
R

redbomber

Bekanntes Mitglied
sorry leute.
Erst einmal hatte ich den code falsch geposted. habe ich eben aktualisiert.
Ich synchronisiere auf
Java:
synchronized(MyClass.class)

Ok, bei diesem Code wäre ich davon ausgegangen dass auf der einigsten Instanz von "MyClass" synchronisiert wird.

Wenn ich diese Methode jedoch anwende, dann erhalte ich unvorhersehbare Antworten aus der Methode DateFormat.parse().
Im grunde genau alle Antowrten die in diesem Post gefunden hatte:

fahd.blog: DateFormat with Multiple Threads

In diesem Post werden mehrere Möglichkeiten angeboten wie ich das problem behebe. Ich hab mich für den synchronized block entschieden.

In meinem Fall wird auf ein DateFormat in dem Array meiner Klasse MyClass immer nur von einem Thread aus zugegriffen.
Genau das was ich möchte.

Nun verstehe ich aber nicht warum meine erste Variante nicht auch funktioniert?
 
Zuletzt bearbeitet:
D

despikyxd

Gast
ich glaube der fehler liegt hier eher bei dir selbst da du dieses NOT THREADSAFE total falsch verstehst ...
NOT THREADSAFE bedeutet nich das man syncen muss ... sondern das es zu einem unerwartetem ereignis innerhalb des aufrufenden threads führen kann ...

also befasse dich bitte erstmal mit dem statement NOT THREADSAFE ... und dann kannst du noch mal selbst überlegen was für einen fehler du begangen hast

tipp : synchronized bedeutet nur das auf eine methode nur eine instanz gleichzeitig zugreifen kann und steht gewöhnlich als modfier in der methoden-signatur
 
S

SlaterB

Gast
@despikyxd
nanu, dann verstehe ich NOT THREADSAFE aber auch falsch..

bei google eingetippt wird man etwa zu
Thread safety - Wikipedia, the free encyclopedia
geleitet, was dort alles steht kann man im Detail lesen und auf verschiedenste Weisen interpretieren, ich zitiere aber zumindest
Mutual exclusion or Process synchronization

Access to shared data is serialized using mechanisms that ensure only one thread reads or writes the shared data at any time.

synchronized-Blöcke statt ganze Methoden sind meiner Ansicht nach auch ok,

könntest du deine Gedanken weiter ausführen?

------

@redbomber
wieso Synchronisierung über die Klasse nicht funktioniert kann ich derzeit nicht sagen,
funktioniert denn das andere? wenn auch nicht, dann muss es generell einen anderen Grund geben
 
Zuletzt bearbeitet von einem Moderator:
R

redbomber

Bekanntes Mitglied
Hmm, also ich habe mir eine Test-Klasse geschrieben, die eben genau das testen soll.
Hier lasse ich mehrere Threads parallel laufen, die auf EINEM DateFormat einen String in eine Date parsen.

1.
Ohne jegliches Synchronized kommt es zu vielen unvorhersagbaren Ergebnissen und Exceptions.
Was auch zu erwarten war.

2.
Synchronisiere ich auf:
Java:
synchonized(MyClass.class){
...
}
Dann klappt der Test leider auch, was nicht zu erwarten war.
Zumindest hatte ich diese Implementierung bisher so und es gab immer wieder Exceptions.

3.
Synchronisiere auf auf das Objekt vom DateFormat
Java:
synchonized(formats[i]){
...
}
Hier klappt der Test.


Da Test 2 auch funktioniert kann ich also nicht mit Sicherheit sagen ob der Fehler nun behoben ist.
 
tfa

tfa

Top Contributor
Dann klappt der Test leider auch, was nicht zu erwarten war.
Warum war das nicht zu erwarten? MyClass.class ist ein globales Objekt, das kann man zum Synchronisieren benutzen.
Ich würde hier gar nicht mit synchronized arbeiten, sondern die Formate einfach lokal erzeugen (wie viele sind das denn? 500?)
 
R

redbomber

Bekanntes Mitglied
Warum war das nicht zu erwarten? MyClass.class ist ein globales Objekt, das kann man zum Synchronisieren benutzen.
Ja ist richtig, ich hatte nur auf MyClass.class synchronisiert und es gab immer wieder unvorhersagbare Ergebnisse.
Wär mein Test hier auch fehlgeschlagen, dann könnte ich zumindest sagen dass es jetzt sicher funktioniert wenn ich auf das passende DateFormat synchronisiere...
Jetzt weiss ich nicht ob meine neue Lösung das Problem wirklich behebt.

also in
Java:
static DateFormat[] formats[]={...}
hab ich mehrere DateFormat Objekte, vielleicht 10.

Die Formate lokal erzeugen ist zu aufwendig, da MyClass.format() an sehr vielen Stellen im Code aufgerufen wird.
In einer Schleife wird dann durch alle Formatter gelaufen, bis ein passendes Ergebnis erzeugt wurde.

Die Synchronisation erscheint mir die einzigste Möglichkeit die ich habe um die unvorhersagbaren Ergebnisse zu vermeiden.
 
Zuletzt bearbeitet:
T

TLA

Gast
Also, wo anfangen? Code, der unvorhersagbare Termine ausgibt - sehr gut^^

2. ThreadLocals
Another approach is to use a ThreadLocal variable to hold the DateFormat object, which means that each thread will have its own copy and doesn't need to wait for other threads to release it. This is generally more efficient

Glaube ich nicht so richtig dran, das es effizienter ist, bei vielen Threads viele Instanzen von DateFormat zu erzeugen.

Über die Instanzen der einzelnen DateFormat zu synchronisieren ist der richtige Weg, allerdings kostete es Zeit, den Block zu betreten und wahrscheinlich ist es effizienter, die ganze Schleife innerhalb des sync-Blocks zu schreiben. Teste das mal, also die Synchronisation auf der Variable des Arrays. So gesehen, wären sogar Änderungen der Array-Elem möglich.
 
F

FArt

Top Contributor
ich glaube der fehler liegt hier eher bei dir selbst da du dieses NOT THREADSAFE total falsch verstehst ...
NOT THREADSAFE bedeutet nich das man syncen muss ... sondern das es zu einem unerwartetem ereignis innerhalb des aufrufenden threads führen kann ...

also befasse dich bitte erstmal mit dem statement NOT THREADSAFE ... und dann kannst du noch mal selbst überlegen was für einen fehler du begangen hast
Entweder erzählst du hier eine Menge Käse, oder du hast dich nur etwas ungünstig ausgedrückt (wovon ich ausgehe). Natürlich muss man eine Stelle, die nicht threadsafe ist nicht synchronisieren. Aber nur wenn es eine single-threaded Anwendung ist. Sonst muss man sie synchronisieren, weil eben wie du schon sagtest sonst unvorhersehbare Ergebnisse (oder Exceptions) auftreten können.

tipp : synchronized bedeutet nur das auf eine methode nur eine instanz gleichzeitig zugreifen kann und steht gewöhnlich als modfier in der methoden-signatur
Von gewöhnlich kann man nicht wirklich sprechen. Kritische Sektionen sollten so klein wie möglich sein, somit ist ein synchronisierter Block u.U. sinnvoll, wenn man nicht die gesamte Methode synchronisieren möchte.
 
R

redbomber

Bekanntes Mitglied
Also erst einmal euch allen vielen vielen Dank!

Über die Instanzen der einzelnen DateFormat zu synchronisieren ist der richtige Weg, allerdings kostete es Zeit, den Block zu betreten und wahrscheinlich ist es effizienter, die ganze Schleife innerhalb des sync-Blocks zu schreiben. Teste das mal, also die Synchronisation auf der Variable des Arrays. So gesehen, wären sogar Änderungen der Array-Elem möglich.
Habe ich ich nicht getestet, werde ich aber prüfen. Versuche auch mal zu messen obs da zeit-unterschiede gibt.

Ich habe jetzt viele Stunden mein Programm laufen lassen und bisher gibt es nur die erwünschten Ergebnisse.
Zuvor kam es bei einer deutlich kürzeren Laufzeit, als ich noch auf MyClass.class synchronisiert hatte, mehrmals zu unvorhersagbaren Ergebnissen.

Meine Test-Klasse funktioniert "leider" bei beiden Varianten. Aber ich denke den Fall, der während des Programm-Ablaufs auftritt ist zu zufällig. Den kann ich in meinem Test nicht wirklich simulieren.
Da das Programm jetzt aber durchgelaufen ist, bin ich zufrieden.
Ich denke ich habs nun mit eurer Hilfe gelöst!
 
T

TLA

Gast
Von gewöhnlich kann man nicht wirklich sprechen. Kritische Sektionen sollten so klein wie möglich sein, somit ist ein synchronisierter Block u.U. sinnvoll

Diese Faustregel gilt immer? Auch für sync-Blöcke mit sehr kurzen Schleifen, die höchstwahrscheinlich sequentiell durchlaufen werden? da lass ich mich auf wette ein.

schlimmstenfalls würde man n*m oft warten müssen, wenn n anzahl der konkurrierenden threads, m anzahl der Formats; bestenfalls 0-mal und bei synchronisation nur einen Formats mindestens n-mal ;)
 
F

FArt

Top Contributor
Diese Faustregel gilt immer? Auch für sync-Blöcke mit sehr kurzen Schleifen, die höchstwahrscheinlich sequentiell durchlaufen werden? da lass ich mich auf wette ein.

schlimmstenfalls würde man n*m oft warten müssen, wenn n anzahl der konkurrierenden threads, m anzahl der Formats; bestenfalls 0-mal und bei synchronisation nur einen Formats mindestens n-mal ;)

Das macht doch so in der Regel keinen Sinn... es geht um kleinere Synchronisationsblöcke als die ganze Methode... und so klein wie möglich aber so groß wie nötig. Wenn es keinen Sinn macht, ist es nicht möglich.
 
T

TLA

Gast
ich bezweifle, dass du weißt, was ich meine. es geht darum, ob

Java:
public static String met() {
    String result = "";
    for (int i = 0; i < 5; i++) {
        synchronized(array[i]) {
        result = array[i].metOther();
        }
    }
    return result;
}

oder

Java:
public static String met() {
    String result = "";
    synchronized(array) {
    for (int i = 0; i < 5; i++) {
        result = array[i].metOther();
    }
    }
    return result;
}

für wieviele threads schneller wäre oder nicht...

unabhängig davon, wie viel sinn das macht, ist
- die schleife relativ kurz,
- kostet der eintritt in den sync-block zeit,
- kann es sein, dass oft die schleife ganz durchlaufen wird, auch bei mehrern gleichzeitig laufenden threads

schwer zu sagen, was schenller wäre. unabhängig (auch) davon sind einige neuere schnellere methoden zur synchronisierung noch gar nicht genannt worden und werden auch nicht in dem blog-beitrag erwähnt - aber darum ging es ja auch eigentlich nicht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Synchronized Probleme Allgemeine Java-Themen 7
D ReentrantLock oder Synchronized ? Allgemeine Java-Themen 3
B Threads synchronized Allgemeine Java-Themen 3
NicoDeluxe Threads und synchronized Allgemeine Java-Themen 9
N Best Practice Semi-Synchronized Zugriff Allgemeine Java-Themen 0
E Verständnisfrage zu synchronized-Blöcken Allgemeine Java-Themen 3
J yield() Aufruf in einer synchronized-Methode Allgemeine Java-Themen 13
A Frage zu Synchronized Allgemeine Java-Themen 5
R synchronized methode rekursiv aufrufen Allgemeine Java-Themen 5
P synchronized Allgemeine Java-Themen 4
S komplexe synchronized bedingungen Allgemeine Java-Themen 6
G synchronized Allgemeine Java-Themen 7
J Threads und synchronized Allgemeine Java-Themen 18
hdi synchronized & volatile Allgemeine Java-Themen 10
G zwei mal synchronized Allgemeine Java-Themen 5
J synchronized block mit this und wait() Allgemeine Java-Themen 5
M Verständnis "synchronized" Allgemeine Java-Themen 4
T Thread synchronized Allgemeine Java-Themen 5
Kr0e Synchronized Allgemeine Java-Themen 4
K synchronized und notify / notifyAll Allgemeine Java-Themen 8
G synchronized-Sclüsselwort: welche Reihenfolge zum Betreten? Allgemeine Java-Themen 6
R synchronized "gegen sich selbst" Allgemeine Java-Themen 5
R ConcurrentModificationException trotz synchronized? Allgemeine Java-Themen 12
R Thread-Problem, und synchronized bringt nix Allgemeine Java-Themen 4
J synchronized (bitte beantworten, urgent! danke) Allgemeine Java-Themen 11
H Ein synchronized Block ausreichend? Allgemeine Java-Themen 6
G synchronized Klasse? Allgemeine Java-Themen 6
G synchronized + threads Allgemeine Java-Themen 12
A deadlocks bei synchronized Allgemeine Java-Themen 3
K vector, synchronized und mehrere methoden Allgemeine Java-Themen 3
M Windows 98 - Mit welchem JDK (Version) kann noch Programm dafür erstellt werden Allgemeine Java-Themen 6
H Aus welchem Land stammt eine URL? Allgemeine Java-Themen 5
S Mit welchem Firefox browser laeuft Java4 ? Allgemeine Java-Themen 2
B in welchem verzeichnis liegen alle installierten klassen? Allgemeine Java-Themen 6
J Erkennen aus welchem Pfad das Jar gestartet wurde Allgemeine Java-Themen 6
K Woher weiss ein Objekt, zu welchem anderen Objekt es gehört? Allgemeine Java-Themen 8
G Mit welchem Betriebssystem programmiert ihr Java und wofür? Allgemeine Java-Themen 11
S mit welchem befehl kann ich mein programm autom. schließen Allgemeine Java-Themen 3
I Mit welchem Tag fängt der Monat an ? Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Objekt in Bytestream umwandeln Allgemeine Java-Themen 12
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
S Neues Objekt darstellen Allgemeine Java-Themen 4
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7

Ähnliche Java Themen

Anzeige

Neue Themen


Oben