You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by nk...@apache.org on 2021/01/05 15:27:56 UTC

[zookeeper] branch master updated: ZOOKEEPER-3671: Use ThreadLocalConcurrent to Replace Random and Math.…

This is an automated email from the ASF dual-hosted git repository.

nkalmar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a6b055  ZOOKEEPER-3671: Use ThreadLocalConcurrent to Replace Random and Math.…
0a6b055 is described below

commit 0a6b055356128483ad4166ca8cd5eff26f66fefb
Author: David Mollitor <dm...@apache.org>
AuthorDate: Tue Jan 5 16:27:46 2021 +0100

    ZOOKEEPER-3671: Use ThreadLocalConcurrent to Replace Random and Math.…
    
    …random
    
    Author: David Mollitor <dm...@apache.org>
    
    Reviewers: Andor Molnar <an...@apache.org>, Norbert Kalmar <nk...@apache.org>
    
    Closes #1199 from belugabehr/ZOOKEEPER-3671
---
 .../src/main/java/org/apache/zookeeper/ClientCnxn.java           | 5 ++---
 zookeeper-server/src/main/java/org/apache/zookeeper/Login.java   | 9 ++++-----
 .../main/java/org/apache/zookeeper/server/quorum/Observer.java   | 3 ++-
 .../zookeeper/server/util/RequestPathMetricsCollector.java       | 8 +++-----
 .../java/org/apache/zookeeper/server/watch/WatcherCleaner.java   | 5 ++---
 5 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
index ecd2a0a..1ff4512 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ClientCnxn.java
@@ -37,11 +37,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Queue;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
 import javax.security.auth.login.LoginException;
 import javax.security.sasl.SaslException;
 import org.apache.jute.BinaryInputArchive;
@@ -869,7 +869,6 @@ public class ClientCnxn {
 
         private long lastPingSentNs;
         private final ClientCnxnSocket clientCnxnSocket;
-        private Random r = new Random();
         private boolean isFirstConnect = true;
 
         void readResponse(ByteBuffer incomingBuffer) throws IOException {
@@ -1134,7 +1133,7 @@ public class ClientCnxn {
             saslLoginFailed = false;
             if (!isFirstConnect) {
                 try {
-                    Thread.sleep(r.nextInt(1000));
+                    Thread.sleep(ThreadLocalRandom.current().nextLong(1000));
                 } catch (InterruptedException e) {
                     LOG.warn("Unexpected exception", e);
                 }
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
index 83af162..e74cddb 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Login.java
@@ -26,8 +26,8 @@ package org.apache.zookeeper;
  */
 
 import java.util.Date;
-import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.kerberos.KerberosPrincipal;
@@ -70,9 +70,6 @@ public class Login {
     private boolean isKrbTicket = false;
     private boolean isUsingTicketCache = false;
 
-    /** Random number generator */
-    private static Random rng = new Random();
-
     private LoginContext login = null;
     private String loginContextName = null;
     private String principal = null;
@@ -341,7 +338,9 @@ public class Login {
         long expires = tgt.getEndTime().getTime();
         LOG.info("TGT valid starting at:        {}", tgt.getStartTime().toString());
         LOG.info("TGT expires:                  {}", tgt.getEndTime().toString());
-        long proposedRefresh = start + (long) ((expires - start) * (TICKET_RENEW_WINDOW + (TICKET_RENEW_JITTER * rng.nextDouble())));
+        long proposedRefresh = start + (long) ((expires - start)
+            * (TICKET_RENEW_WINDOW + (TICKET_RENEW_JITTER
+                * ThreadLocalRandom.current().nextDouble())));
         if (proposedRefresh > expires) {
             // proposedRefresh is too far in the future: it's after ticket expires: simply return now.
             return Time.currentWallTime();
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Observer.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Observer.java
index fbf1d55..55e273b 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Observer.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Observer.java
@@ -20,6 +20,7 @@ package org.apache.zookeeper.server.quorum;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import java.nio.ByteBuffer;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.jute.Record;
 import org.apache.zookeeper.server.ObserverBean;
@@ -255,7 +256,7 @@ public class Observer extends Learner {
 
     private static void waitForReconnectDelayHelper(long delayValueMs) {
         if (delayValueMs > 0) {
-            long randomDelay = (long) (delayValueMs * Math.random());
+            long randomDelay = ThreadLocalRandom.current().nextLong(delayValueMs);
             LOG.info("Waiting for {} ms before reconnecting with the leader", randomDelay);
             try {
                 Thread.sleep(randomDelay);
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/RequestPathMetricsCollector.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/RequestPathMetricsCollector.java
index f3ec1fc..db6f8c5 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/RequestPathMetricsCollector.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/RequestPathMetricsCollector.java
@@ -40,13 +40,13 @@ import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Random;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
@@ -86,7 +86,6 @@ public class RequestPathMetricsCollector {
     private static final String PATH_SEPERATOR = "/";
 
     private final Map<String, PathStatsQueue> immutableRequestsMap;
-    private final Random sampler;
     private final ScheduledThreadPoolExecutor scheduledExecutor;
     private final boolean accurateMode;
 
@@ -96,7 +95,6 @@ public class RequestPathMetricsCollector {
 
     public RequestPathMetricsCollector(boolean accurateMode) {
         final Map<String, PathStatsQueue> requestsMap = new HashMap<>();
-        this.sampler = new Random(System.currentTimeMillis());
         this.accurateMode = accurateMode;
 
         REQUEST_PREPROCESS_TOPPATH_MAX = Integer.getInteger(PATH_STATS_TOP_PATH_MAX, 20);
@@ -204,7 +202,7 @@ public class RequestPathMetricsCollector {
         if (!enabled) {
             return;
         }
-        if (sampler.nextFloat() <= REQUEST_PREPROCESS_SAMPLE_RATE) {
+        if (ThreadLocalRandom.current().nextFloat() <= REQUEST_PREPROCESS_SAMPLE_RATE) {
             PathStatsQueue pathStatsQueue = immutableRequestsMap.get(Request.op2String(type));
             if (pathStatsQueue != null) {
                 pathStatsQueue.registerRequest(path);
@@ -357,7 +355,7 @@ public class RequestPathMetricsCollector {
                 return;
             }
             // Staggered start and then run every 15 seconds no matter what
-            int delay = sampler.nextInt(REQUEST_STATS_SLOT_DURATION);
+            int delay = ThreadLocalRandom.current().nextInt(REQUEST_STATS_SLOT_DURATION);
             // We need to use fixed Delay as the fixed rate will start the next one right
             // after the previous one finishes if it runs overtime instead of overlapping it.
             scheduledExecutor.scheduleWithFixedDelay(() -> {
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/watch/WatcherCleaner.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/watch/WatcherCleaner.java
index 1f809cf..be98f98 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/watch/WatcherCleaner.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/watch/WatcherCleaner.java
@@ -19,8 +19,8 @@
 package org.apache.zookeeper.server.watch;
 
 import java.util.HashSet;
-import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.zookeeper.common.Time;
 import org.apache.zookeeper.server.RateLogger;
@@ -50,7 +50,6 @@ public class WatcherCleaner extends Thread {
     private volatile boolean stopped = false;
     private final Object cleanEvent = new Object();
     private final Object processingCompletedEvent = new Object();
-    private final Random r = new Random(System.nanoTime());
     private final WorkerService cleaners;
 
     private final Set<Integer> deadWatchers;
@@ -133,7 +132,7 @@ public class WatcherCleaner extends Thread {
                     // same time in the quorum
                     if (!stopped && deadWatchers.size() < watcherCleanThreshold) {
                         int maxWaitMs = (watcherCleanIntervalInSeconds
-                                         + r.nextInt(watcherCleanIntervalInSeconds / 2 + 1)) * 1000;
+                                         + ThreadLocalRandom.current().nextInt(watcherCleanIntervalInSeconds / 2 + 1)) * 1000;
                         cleanEvent.wait(maxWaitMs);
                     }
                 } catch (InterruptedException e) {