ndimiduk commented on a change in pull request #2523:
URL: https://github.com/apache/hbase/pull/2523#discussion_r509538496



##########
File path: 
hbase-server/src/main/java/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.java
##########
@@ -71,38 +76,81 @@
   static final String MERGE_MIN_REGION_SIZE_MB_KEY = 
"hbase.normalizer.merge.min_region_size.mb";
   static final int DEFAULT_MERGE_MIN_REGION_SIZE_MB = 1;
 
-  private Configuration conf;
   private MasterServices masterServices;
-  private boolean splitEnabled;
-  private boolean mergeEnabled;
-  private int minRegionCount;
-  private Period mergeMinRegionAge;
-  private int mergeMinRegionSizeMb;
+
+  /** Ensure configuration changes are applied atomically. */
+  private final ReadWriteLock configUpdateLock = new ReentrantReadWriteLock();
+  @GuardedBy("configUpdateLock") private Configuration conf;
+  @GuardedBy("configUpdateLock") private boolean splitEnabled;
+  @GuardedBy("configUpdateLock") private boolean mergeEnabled;
+  @GuardedBy("configUpdateLock") private int minRegionCount;
+  @GuardedBy("configUpdateLock") private Period mergeMinRegionAge;
+  @GuardedBy("configUpdateLock") private int mergeMinRegionSizeMb;
 
   public SimpleRegionNormalizer() {
-    splitEnabled = DEFAULT_SPLIT_ENABLED;
-    mergeEnabled = DEFAULT_MERGE_ENABLED;
-    minRegionCount = DEFAULT_MIN_REGION_COUNT;
-    mergeMinRegionAge = Period.ofDays(DEFAULT_MERGE_MIN_REGION_AGE_DAYS);
-    mergeMinRegionSizeMb = DEFAULT_MERGE_MIN_REGION_SIZE_MB;
+    final Lock writeLock = configUpdateLock.writeLock();
+    writeLock.lock();
+    try {
+      splitEnabled = DEFAULT_SPLIT_ENABLED;
+      mergeEnabled = DEFAULT_MERGE_ENABLED;
+      minRegionCount = DEFAULT_MIN_REGION_COUNT;
+      mergeMinRegionAge = Period.ofDays(DEFAULT_MERGE_MIN_REGION_AGE_DAYS);
+      mergeMinRegionSizeMb = DEFAULT_MERGE_MIN_REGION_SIZE_MB;
+    } finally {
+      writeLock.unlock();
+    }
   }
 
   @Override
   public Configuration getConf() {
-    return conf;
+    final Lock readLock = configUpdateLock.readLock();
+    readLock.lock();
+    try {
+      return conf;
+    } finally {
+      readLock.unlock();
+    }
   }
 
   @Override
   public void setConf(final Configuration conf) {
     if (conf == null) {
       return;
     }
-    this.conf = conf;
-    splitEnabled = conf.getBoolean(SPLIT_ENABLED_KEY, DEFAULT_SPLIT_ENABLED);
-    mergeEnabled = conf.getBoolean(MERGE_ENABLED_KEY, DEFAULT_MERGE_ENABLED);
-    minRegionCount = parseMinRegionCount(conf);
-    mergeMinRegionAge = parseMergeMinRegionAge(conf);
-    mergeMinRegionSizeMb = parseMergeMinRegionSizeMb(conf);
+
+    final Lock readLock = configUpdateLock.readLock();
+    final Lock writeLock = configUpdateLock.writeLock();
+    writeLock.lock(); // "a writer can acquire the read lock, but not 
vice-versa."
+    readLock.lock();

Review comment:
       > Why is readLock.lock() called here? Thought writeLock is enough.
   
   Initially I thought so too, but reading the docs on `ReadWriteLock`, it 
never explicitly said that the `WriteLock` is exclusive for both readers and 
writers, it only says that it's exclusive. The best I can find is from _Java 
Concurrency in Practice_, which says (emphasis mine):
   
   > ... Mutual exclusion is a conservative locking strategy that prevents 
writer/writer and writer/reader overlap, but also prevents reader/reader 
overlap. In many cases, data structures are “read-mostly”—they are mutable and 
are sometimes modified, but most accesses involve only reading. In these cases, 
it would be nice to relax the locking requirements to allow multiple readers to 
access the data structure at once. As long as each thread is guaranteed an 
up-to-date view of the data and no other thread modifies the data while the 
readers are viewing it, there will be no problems. **This is what read-write 
locks allow: a resource can be accessed by multiple readers or a single writer 
at a time, but not both.**
   
   So I think you're correct @huaxiangsun , the write lock should be sufficient.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to