1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.Delayed;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.RunnableScheduledFuture;
28 import java.util.concurrent.ScheduledThreadPoolExecutor;
29 import java.util.concurrent.ThreadFactory;
30 import java.util.concurrent.ThreadLocalRandom;
31 import java.util.concurrent.TimeUnit;
32 import java.util.concurrent.TimeoutException;
33
34
35
36
37
38
39 @InterfaceAudience.Private
40 public class JitterScheduledThreadPoolExecutorImpl extends ScheduledThreadPoolExecutor {
41 private final double spread;
42
43
44
45
46
47 public JitterScheduledThreadPoolExecutorImpl(int corePoolSize,
48 ThreadFactory threadFactory,
49 double spread) {
50 super(corePoolSize, threadFactory);
51 this.spread = spread;
52 }
53
54 @Override
55 protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(
56 Runnable runnable, java.util.concurrent.RunnableScheduledFuture<V> task) {
57 return new JitteredRunnableScheduledFuture<>(task);
58 }
59
60 @Override
61 protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(
62 Callable<V> callable, java.util.concurrent.RunnableScheduledFuture<V> task) {
63 return new JitteredRunnableScheduledFuture<>(task);
64 }
65
66
67
68
69
70 protected class JitteredRunnableScheduledFuture<V> implements RunnableScheduledFuture<V> {
71 private final RunnableScheduledFuture<V> wrapped;
72 JitteredRunnableScheduledFuture(RunnableScheduledFuture<V> wrapped) {
73 this.wrapped = wrapped;
74 }
75
76 @Override
77 public boolean isPeriodic() {
78 return wrapped.isPeriodic();
79 }
80
81 @Override
82 public long getDelay(TimeUnit unit) {
83 long baseDelay = wrapped.getDelay(unit);
84 long spreadTime = (long) (baseDelay * spread);
85 long delay = spreadTime <= 0 ? baseDelay
86 : baseDelay + ThreadLocalRandom.current().nextLong(-spreadTime, spreadTime);
87
88 return (delay < 0) ? baseDelay : delay;
89 }
90
91 @Override
92 public int compareTo(Delayed o) {
93 return wrapped.compareTo(o);
94 }
95
96 @Override
97 public boolean equals(Object obj) {
98 if (obj == this) {
99 return true;
100 }
101 return obj instanceof Delayed? compareTo((Delayed)obj) == 0: false;
102 }
103
104 @Override
105 public int hashCode() {
106 return this.wrapped.hashCode();
107 }
108
109 @Override
110 public void run() {
111 wrapped.run();
112 }
113
114 @Override
115 public boolean cancel(boolean mayInterruptIfRunning) {
116 return wrapped.cancel(mayInterruptIfRunning);
117 }
118
119 @Override
120 public boolean isCancelled() {
121 return wrapped.isCancelled();
122 }
123
124 @Override
125 public boolean isDone() {
126 return wrapped.isDone();
127 }
128
129 @Override
130 public V get() throws InterruptedException, ExecutionException {
131 return wrapped.get();
132 }
133
134 @Override
135 public V get(long timeout,
136 TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
137 return wrapped.get(timeout, unit);
138 }
139 }
140 }