2009-06-14 8 views
0

Ich habe eine einfache Methode, die aus mehreren Threads aufgerufen wird;Java-Synchronisation - Brauche ich es für diese einfache Methode?

@Override 
public Bitmap getFullBitmap(Filter f, ProgressCallback<String> pc) { 
    // Requires synchronisation? 
    Bitmap bitmap = fullMap.get(f.id); 
    if(bitmap == null){ 
     f.setProgressCallback(pc); 
     bitmap = f.e.evaluate(currentBitmap); 
     fullMap.put(f.id, bitmap); 
    } 
    return bitmap; 
} 

Da keines der Objekte verwendet werden Felder der Klasse (abgesehen von fullMap) ist es nur ok dies zu nennen oder auch den Wert von Bitmap zum Beispiel ein Thread ändern, während das Verfahren ausgeführt wird?

fullMap ist eine SoftHashMap, die SoftReferences von indizierten Bitmap-Objekten verwaltet, aber die ID des Filters, mit der sie erstellt wurde. Wenn das irgendeinen Sinn ergibt.

Ich hatte keine Probleme, aber ich dachte, ich könnte es brauchen.

Bitte fragen Sie nach Klärung, wenn dies nicht klar ist, macht die Frage Sinn in meinem Kopf;)

EDIT

  • currentBitmap ist ein Objekt vom Typ Bitmap, gibt es eine Bitmap in der System, das als aktuell angesehen wird und von dieser Klasse verwaltet wird.
  • Dieser Code bildet einen sehr einfachen Cache, Die zurückgegebene Bitmap ist immer das gleiche für jede ID und ist nicht geändert außerhalb dieser Methode.
  • von Soft-Referenzen in einer SoftHashMap Verwendung als durch Dr Heinx und eine FIFO-Warteschlange von harten Referenzen für die 10 zuletzt descibed habe ich teure Anrufe f.e.evaluate zu vermeiden hoffen. Das heißt, der Aufruf von e.evaluate wird ein identisches Bitmap-Objekt zurückgeben, wenn es die gleiche Eingabe gegeben hat. Nach ein paar dachte, es scheint, dass die Synchronisierung die Methode ist eine gute Idee, wie nichts positive kommt von zwei Threads Ausführung dieses Codes für die gleichen Filter.
  • Zusätzlich habe ich Bitmap-Finale gemacht, wie es sollte nach der Erstellung nicht mutiert werden.

Vielen Dank! Gav

+0

was ist currentBitmap? – akf

Antwort

4

2 Threads könnten auf die Karte fullMap gleichzeitig zugreifen. Beide könnten feststellen, dass die Karte keinen Wert für denselben Schlüssel enthält, jeder einen erstellen und dann zurückschreiben, wodurch ein Schlüssel zweimal eingefügt wird.

Dies kann nicht ein Problem jenseits der Effizienz sein. Dies kann jedoch Verwirrung stiften und in Zukunft zu Problemen bei der Entwicklung Ihrer Lösung führen (wie teuer wird es sein, diese Objekte in Zukunft zu erstellen? Was passiert, wenn jemand den Code irgendwo unpassender kopiert/einfügt)?)

würde ich stark von der oben empfehlen (höchstwahrscheinlich auf fullMap selbst eher als das enthaltende Objekt zu synchronisieren, aber mehr Kontext vor der Entscheidung genau nützlich sein würde, was erforderlich ist)

+0

Das Nachbestellen von Anweisungen ist nicht die Quelle der Rennbedingung, von der Sie sprechen. Es ist eine einfache Multi-Thread-Race-Bedingung. – Eddie

+0

Ich glaube nicht, dass das Problem der doppelten Überprüfung hier gilt, da Bitmap kein Feld ist. Zu dem Zeitpunkt, zu dem das Objekt in die Karte gelangt, sollte es richtig konstruiert sein. Außerdem sollte ein zweimaliger Hinzufügen eines Schlüssels zur Map nur dann ein Problem darstellen, wenn Sie aus irgendeinem Grund nur den Wert des ersten Schlüssel-Wert-Paares wünschen. Andernfalls überschreibt der zweite Wert nur den ersten. Trotzdem denke ich, dass Sie wahrscheinlich recht haben, wenn Sie auf der Karte synchronisieren, denn Sie selbst sind möglicherweise nicht Thread-sicher. –

+1

@Matthew - bearbeitet, um zu reflektieren, dass das Einfügen eines Schlüssels zweimal kein Problem jenseits der Effizienz –

0

Wenn Ihre Methode nur übergebene Parameter und lokale Variablen ohne gemeinsamen Status verwendet, würde ich sagen, dass sie Thread-sicher ist und keine Synchronisation erforderlich ist.

Gewindesicherheit muss sich um veränderlichen, gemeinsamen Zustand kümmern. Ist Fullmap ein Teil des Zustands dieses Objekts? Wenn ja, müssen Sie den Zugriff synchronisieren.

2

SoftHashMap.put selbst seine gerade nicht Thread kann -sicher. SoftHashMap ist nicht in der Standardbibliothek, aber WeakHashMap ist, und es ist nicht synchronisiert. Neben der Synchronisierung der Methode auf der Karte möchten Sie möglicherweise Collections.synchronizedMap verwenden, um sicherzustellen, dass andere Methoden die Karte nicht gleichzeitig ändern.

0

Ich würde für den Synchronisationspfad entscheiden, wenn das zurückgegebene Bitmap außerhalb der Methode geändert wird. Sie riskieren, dass zwei Threads auf die obige Methode zugreifen, während die Bitmap in f.id gleich null ist. Sie erstellen jeweils einen Thread und fügen ihn zur Map hinzu, wobei der zweite den ersten in der Map überschreibt. Jetzt haben Sie zwei, eine, die durch thread-1 geändert wird, aber außerhalb des Geltungsbereichs ist, sobald thread-1 mit ihrer Verarbeitung fertig ist, und die andere von thread-2, die in der Map verbleiben und für alle zukünftigen bereitgestellt werden Anforderer.

1

Sie brauchen unbedingt eine Synchronisation, weil Sie zwei Threads entscheiden können, dass f.id nicht in der Karte ist, konstruieren und dann eins hinzufügen. Jeder Thread wird eine Differenzinstanz für f.id zurückgegeben, obwohl die Karte nur die letzte enthält.

In Frage ist nicht die Variable bitmap. Das ist threadsicher, da es sich um einen einzelnen Thread handelt. Der Zugriff auf "fullMap" - was ich für ein Feld der Klasse halte - muss jedoch aufgrund der Tatsache, dass Sie ein "Put-If-Abwesend" -Modus durchführen, synchronisiert werden.

Angenommen, die Kosten für die Erstellung einer Bitmap sind teuer, der beste Weg, dies zu tun, ist nur die Methode getFullBitmap() zu synchronisieren. Wenn es sehr billig zu konstruieren war - billiger als Synchronisation - dann würde ich vorschlagen, immer das neue Objekt zu konstruieren und putIfAbsent auf einem ConcurrentMap zu tun. Aber wenn das Objekt teuer zu konstruieren ist, ist dies eine schlechte Idee.

0

Ich bin mir nicht sicher, aber AFAIK Sie könnten eine Art "Concurent Modification Exception" geworfen werden, wenn Sie Code haben, über die "fullMap" iterieren. Dies muss nicht in Ihrem Code sein, aber könnte in den Bibliotheksroutinen für SoftMap passieren. Dies kann dazu führen, dass Ihr Code zur Laufzeit gelegentlich ohne erkennbaren Grund und ohne einen guten Weg für Sie die Situation zu brechen.

Nur eine komplizierte Art zu sagen: "Im Zweifel, sei vorsichtig". BTW: Denken Sie nicht zuerst an Leistung mit heutigen Computern.

Happy Hacking

Huibert Gill

Verwandte Themen