CryptoServicesRegistrar caches any default SecureRandom
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
- private static volatile SecureRandom defaultSecureRandom;
+ private static final Object cacheLock = new Object();
+ private static SecureRandom defaultSecureRandom;
static
{
@@ -103,17 +104,29 @@ private CryptoServicesRegistrar()
* Return the default source of randomness.
*
* @return the default SecureRandom
- * @throws IllegalStateException if no source of randomness has been provided.
*/
public static SecureRandom getSecureRandom()
{
- if (defaultSecureRandom == null)
+ synchronized (cacheLock)
{
- return new SecureRandom();
+ if (null != defaultSecureRandom)
+ {
+ return defaultSecureRandom;
+ }
+ }
+
+ SecureRandom tmp = new SecureRandom();
+
+ synchronized (cacheLock)
+ {
+ if (null == defaultSecureRandom)
+ {
+ defaultSecureRandom = tmp;
}
return defaultSecureRandom;
}
+ }
/**
* Set a default secure random to be used where none is otherwise provided.
@@ -124,8 +137,11 @@ public static void setSecureRandom(SecureRandom secureRandom)
{
checkPermission(CanSetDefaultRandom);
+ synchronized (cacheLock)
+ {
defaultSecureRandom = secureRandom;
}
+ }
/**
* Return the default value for a particular property if one exists. The look up is done on the thread's local
