2017-02-17 2 views
1

Ich bin auf der Suche nach einer Lösung, die mehrere Threads zum Lesen der freigegebenen Ressource (Parallelität zulässig) erlaubt, aber dann diese Lese-Threads sperren, sobald ein Thread in einen mutierenden Block eintritt, um das Beste aus beiden Welten zu erreichen.gleichzeitig lesen, aber mit Änderungen sperren

class Foo { 

    Map<String, String> sharedResource; 

    public void read() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating block below. 
    { 
     // read concurrently unless a thread enters mutating blocks add/remove 
    } 

    public void add() // this should lock any threads entering this block as well as lock the reading threads above 
    { 
     synchronized(sharedResource) // lock remove and read 
     { 
     } 
    } 

    public void remove() // lock add and read 
    { 
     synchronized(sharedResource) 
     { 
     } 
    } 
} 

Gibt es eine solche Lösung in Java?

Antwort

4

Es ist ein klassisches Lese-/Schreibsperre Szenario:

class Foo { 

    Map<String, String> sharedResource; 
    ReadWriteLock lock = new ReentrantReadWriteLock(); 

    public void read() { 
     lock.readLock().lock(); 
     try { 
      // read 
     } finally { 
      lock.readLock().unlock(); 
     } 
    } 

    public void add() { 
     lock.writeLock().lock(); 
     try { 
      // add 
     } finally { 
      lock.writeLock().unlock(); 
     } 
    } 

    public void remove() { 
     lock.writeLock().lock(); 
     try { 
      // remove 
     } finally { 
      lock.writeLock().unlock(); 
     } 
    } 
} 

Die Lesesperre gemeinsam genutzt werden kann, aber die Schreibsperre ist exklusiv für beide lesen und schreiben.

+0

Danke für das Beispiel, dies scheint die eine, schnelle Frage Ich habe mit 'ConcurrentDictionary' in' C# 'gearbeitet, was sagst du über' ConcurrentHashMap' in Java, ist es etwas vergleichbar mit dem, was Sie gegeben haben ich als Antwort? – user2727195

+0

Angenommen, es handelt sich tatsächlich um eine Map, über die wir dann in einigen Map-Implementierungen lesen, wird die Map tatsächlich mutiert: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html . Sie müssen sicherstellen, dass die Map-Implementierung mit Ihrer Sperrstrategie übereinstimmt. Darüber hinaus gibt es auch Map-Implementierungen, die mehrere Reader ohne externe Sperre effektiv zulassen: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html. –

+0

@ user2727195 'ConcurrentHashMap' ist normalerweise die empfohlene Lösung in Fällen wie deins. – shmosel

Verwandte Themen