2017-02-01 1 views
1

Ich habe eine Klasse, auf die mehrere Threads zugreifen, und ich möchte sicherstellen, dass es threadsicher ist. Außerdem muss es so schnell wie möglich sein. Dies ist nur ein Beispiel:Synchronisierte VS Striped Lock

public class SharedClass { 
    private final Map<String, String> data = new HashMap<>(); 
    private final Striped<ReadWriteLock> rwLockStripes = Striped.readWriteLock(100); 

    public void setSomethingFastVersion(String key, String value) { 
    ReadWriteLock rwLock = rwLockStripes.get(key); 
    try { 
     rwLock.lock(); 
    } finally{ 
     rwLock.unLock(); 
    } 

    data.put(key, value); 
    } 

    public synchronized void setSomethingSlowVersion(String key, String value) { 
    data.put(key, value); 
    } 
} 

Ich verwende StripedLock von Google Guava in einer Version, und ein normales synchronized auf dem anderen.

Stimmt es, dass die Guava-Version schneller sein sollte?

Wenn ja, was wäre ein guter Anwendungsfall für synchronized, wo die StripedLocks würde nicht passen?

Übrigens, ich weiß, ich könnte hier eine einfache ConcurrentHashMap verwenden, aber ich füge den Beispielcode hinzu, um sicherzustellen, dass Sie meine Frage verstehen.

+0

Zuerst muss Ihr 'data.put (k, v)' in Ihrem 'try' Block sein. Im Allgemeinen sind bestimmte verwaltete Sperren schneller als die Synchronisierung. Benchmarking wird bestimmen, ob das in Ihrem Fall der Fall ist. Sie verwenden hier auch eine ReadWrite-Sperre. Brauchst du dieses Verhalten? Ich sehe hier keine Lektüre, wie würdest du sie umsetzen? – WillD

+0

@WillD was kann man dann anstelle von 'ReadWriteLock' verwenden? – Will

+0

[ReentrantLock] (https://docs.oracle.com/javase/lock/docs/api/java/util/concurrent/locks/ReentrantLock.html) – WillD

Antwort

-1

Verwenden Sie eine ConcurrentHashMap, so dass Sie keine eigene Synchronisierung durchführen müssen.

+0

Lies meine Frage, ich sagte: "Übrigens, ich weiß, ich könnte hier eine einfache ConcurrentHashMap verwenden, aber ich füge den Beispielcode hinzu, um sicherzugehen, dass du meine Frage verstehst." – Will

1

Synchron ist schon seit Ewigkeiten. Es ist nicht wirklich überraschend, dass wir heutzutage fortschrittlichere Mechanismen für die gleichzeitige Programmierung haben.

Allerdings sind gestreifte Sperren nur in Fällen von Vorteil, in denen etwas partitioniert oder gestreift sein kann, z. B. das Sperren von Teilen einer Karte, die die gleichzeitige Manipulation verschiedener Teile erlaubt, aber gleichzeitiges Manipulieren desselben Streifens. In vielen Fällen haben Sie diese Art von Partitionierung nicht, Sie suchen nur nach einem Mutex. In diesen Fällen ist synchronized immer noch eine praktikable Option, obwohl eine ReadWriteLock je nach Situation eine bessere Wahl sein könnte.

+0

Hallo, ist ein 'ReadWriteLock' schneller in diesem bestimmtes Szenario dann, denkst du? Kann ich auch etwas anderes als ein 'ReadWriteLock' verwenden? In meinem Fall ist es eigentlich eine 'HashMap', aber ich muss viel daran arbeiten, so dass selbst eine' ConcurrentHashMap' nicht passen würde, deshalb denke ich daran, zu einer normalen 'HashMap' zurückzukehren und verwende Sperren – Will

+0

Nein, ich erklärte eine Situation, in der eine gestreifte Sperre keinen Vorteil hat, und wo "synchronisiert" immer noch eine praktikable Option ist. – Kayaman

+0

Oh OK, ich sehe Entschuldigung. In meinem Fall ist es eine Hash-Karte, also ja, eine Sperre kann es tun – Will