简体   繁体   English

带hashmap的廉价读写锁

[英]Cheap read-write lock with hashmap

 static volatile Map currentMap = null;   // this must be volatile
static Object lockbox = new Object();  
 
public static void buildNewMap() {       // this is called by the producer     
    Map newMap = new HashMap();          // when the data needs to be updated
 
    synchronized (lockbox) {                 // this must be synchronized because
                                         // of the Java memory model
      // .. do stuff to put things in newMap
      newMap.put(....);
      newMap.put(....);
   }                 
/* After the above synchronization block, everything that is in the HashMap is 
   visible outside this thread */
 
/* Now make the updated set of values available to the consumer threads.  
   As long as this write operation can complete without being interrupted, 
   and is guaranteed to be written to shared memory, and the consumer can 
   live with the out of date information temporarily, this should work fine */
 
    currentMap = newMap;
 
}
public static Object getFromCurrentMap(Object key) {
    Map m = null;
    Object result = null;
 
    m = currentMap;               // no locking around this is required
    if (m != null) {              // should only be null during initialization
      Object result = m.get(key); // get on a HashMap is not synchronized
     
      // Do any additional processing needed using the result
    }
    return(result);
 
}

This is a code sample from this articlehttps://www.ibm.com/developerworks/library/j-hashmap/index.html I still don't understand why we need a synchronized block in buildNewMap method.这是本文的代码示例https://www.ibm.com/developerworks/library/j-hashmap/index.html我仍然不明白为什么我们需要在 buildNewMap 方法中使用同步块。 What additional visibility guarantees it produces beside that volatile publishing at currentMap = newMap;除了 currentMap = newMap; does.做。 When we read map reference at m = currentMap;当我们在 m = currentMap 处读取 map 参考时; we rely upon volatile read-write and reading thread doesn't even know about syncronization in producer thread....我们依赖 volatile 读写和读取线程甚至不知道生产者线程中的同步....

If the hashmap is only modified before it is written to the 'currentMap' its content is guaranteed to be visible to other threads.如果 hashmap 仅在写入“currentMap”之前被修改,则保证其内容对其他线程可见。 This is because there is a happens before edge between writing map content and writing to currentMap (program order);这是因为在写入 map 内容和写入 currentMap(程序顺序)之间有一个发生在边缘之前; and there is a happens-before edge (volatile variable) between reading the concurrentMap, and there is a happens before edge between reading the variable and reading the content (program order).并且在读取concurrentMap之间有一个happens-before边缘(易失性变量),并且在读取变量和读取内容(程序顺序)之间有一个happens before edge。 Since happens before is transitive, there is a happens beforge edge between writing the content and reading the content.由于happens before 是可传递的,因此在写入内容和读取内容之间存在一个happens beforge 边缘。

The synchronized block doesn't seem to serve any purpose.同步块似乎没有任何用途。

Java memory model provides strong guarantees regarding volatile writes, according to this article: Java memory model 为易失性写入提供了强有力的保证,根据这篇文章:

http://tutorials.jenkov.com/java-concurrency/volatile.html http://tutorials.jenkov.com/java-concurrency/volatile.html

In particular:尤其是:

  • If Thread A writes to a volatile variable and Thread B subsequently reads the same volatile variable, then all variables visible to Thread A before writing the volatile variable, will also be visible to Thread B after it has read the volatile variable.如果线程 A 写入一个 volatile 变量,而线程 B 随后读取了同一个 volatile 变量,那么线程 A 在写入 volatile 变量之前对线程 A 可见的所有变量,在线程 B 读取 volatile 变量之后也将对线程 B 可见。
  • If Thread A reads a volatile variable, then all all variables visible to Thread A when reading the volatile variable will also be re-read from main memory.如果线程 A 读取一个 volatile 变量,那么在读取 volatile 变量时线程 A 可见的所有变量也将从主 memory 重新读取。

So it looks like the synchronized block is unnecessary.所以看起来同步块是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 廉价的读写锁中的冗余挥发? - redundant volatile in cheap read-write lock? 同步对易失性字段的写入访问(廉价读写块) - Synchronize write access to Volatile field (Cheap read-write block) 将volatile和synchronized混合为读写锁 - Mix volatile and synchronized as a read-write lock 为什么TreeBin在ConcurrentHashMap中保持读写锁定? - why TreeBin maintains a read-write lock in ConcurrentHashMap? 如何使用 JUnit 测试读写锁? - How to test read-write lock using JUnit? 在读写原子性、可见性和防止重新排序方面,锁定、同步、原子变量与 Java 中的 volatile - Lock vs synchronized vs atomic variables vs volatile in java in terms of read-write atomicity, visibility and protection from reordering Java中读写操作的易变变量 - Volatile variable for read-write operations in Java 有关读写锁的查询 - Query regarding read-write locks 为什么 Spring 中的 ConcurrentLruCache 即使使用了读写锁,仍然使用线程安全的映射和队列,而不是普通的映射和队列? - Why does ConcurrentLruCache in Spring still use thread-safe maps and queues instead of ordinary maps and queues even when read-write lock are used? Java中的StoreStore memory屏障是否禁止读写重新排序? - Does StoreStore memory barrier in Java forbid the read-write reordering?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM