回答:
はい、そうです。これはRandom
、事実上スレッドセーフな実装を常に備えていたを拡張し、Java 7以降、スレッドセーフを明示的に保証しています。
多くのスレッドが単一のを使用している場合SecureRandom
、パフォーマンスを低下させる競合が発生する可能性があります。一方、SecureRandom
インスタンスの初期化は比較的遅くなる可能性があります。グローバルRNGを共有するか、スレッドごとに新しいRNGを作成するかは、アプリケーションによって異なります。ThreadLocalRandom
クラスがサポートしているソリューションを提供するためのパターンとして使用することができSecureRandom
。
SecureRandom
遅くなるだけでなく、エントロピーがないためにハングする可能性があります
の現在の実装SecureRandom
はスレッドセーフであり、具体的には2つの変更メソッドでnextBytes(bytes[])
ありsetSeed(byte[])
、同期されています。
さて、私が知る限り、すべての変更メソッドは最終的にこれら2つのメソッドを介してルーティングされ、それを確実SecureRandom
にRandom
するためにいくつかのメソッドをオーバーライドします。これは機能しますが、将来実装が変更されると脆弱になる可能性があります。
最善の解決策は、SecureRandom
最初にインスタンスで手動で同期することです。これは、各コールスタックが同じオブジェクトで2つのロックを取得することを意味しますが、最近のJVMでは通常、非常に安価です。つまり、明示的に自分自身を同期しても、それほど害はありません。例えば:
SecureRandom rnd = ...;
byte[] b = new byte[NRANDOM_BYTES];
synchronized (rnd) {
rnd.nextBytes(b);
}
java.security.SecureRandom#nextBytes
Java 8では同期されません。同期したJavaのバージョンを指定してください#nextBytes
。