Skip to content

Commit e66bda8

Browse files
committed
JAVA-1164: Replaced use of ThreadLocal<Random> subclass (used to override initialValue()) with a method that explicitly gets the thread local value and sets it if it's null.
This avoids some nasty classloader issues that show up particularly in web applications, where this anonymous subclass is holding a reference to the entire web app classloader, which is not released until the thread exits.
1 parent 58e6abf commit e66bda8

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

src/main/com/mongodb/BaseCluster.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ abstract class BaseCluster implements Cluster {
3636

3737
private final AtomicReference<CountDownLatch> phase = new AtomicReference<CountDownLatch>(new CountDownLatch(1));
3838
private final ClusterableServerFactory serverFactory;
39-
private final ThreadLocal<Random> random = new ThreadLocal<Random>() {
40-
@Override
41-
protected Random initialValue() {
42-
return new Random();
43-
}
44-
};
39+
private final ThreadLocal<Random> random = new ThreadLocal<Random>();
4540
private final String clusterId;
4641
private final ClusterSettings settings;
4742
private final ClusterListener clusterListener;
@@ -220,8 +215,15 @@ private void throwIfIncompatible(final ClusterDescription curDescription) {
220215
}
221216
}
222217

223-
protected Random getRandom() {
224-
return random.get();
218+
// it's important that Random instances are created in this way instead of via subclassing ThreadLocal and overriding the
219+
// initialValue() method.
220+
private Random getRandom() {
221+
Random result = random.get();
222+
if (result == null) {
223+
result = new Random();
224+
random.set(result);
225+
}
226+
return result;
225227
}
226228

227229
protected ClusterableServer createServer(final ServerAddress serverAddress, final ChangeListener<ServerDescription>

0 commit comments

Comments
 (0)