18

Random複数のスレッドで(シードされた) オブジェクトを使用しようとしてThreadLocalRandomいますが、シードを設定できないことを除いて、javadocs は見栄えが良いことを指摘しているため、異なるスレッドまたは実行間の一貫性を確保できません。使用する実用的な理由はありますThreadLocalRandomか、または次のようなことをしてもよいでしょうか:

// Pass returned ThreadLocal object to all threads which need it
public static ThreadLocal<Random> threadRandom(final long seed) {
    return new ThreadLocal<Random>(){
        @Override
        protected Random initialValue() {
            return new Random(seed);
        }
    };
}
4

4 に答える 4

9

各オブジェクトが単一のスレッド内でのみアクセスされることRandomを確認してください。Random

Randomは のような古いクラスVectorであり、不必要に高度に同期化されています。当時は大したことだったので、Java のスレッド化サポートを自慢したかったのでしょう。また、Java は主にシングル プロセッサを搭載した消費者向け PC で実行することを目的としていたため、現在のマルチプロセッサのように同期がスケーリングに影響を与えることはありませんでした。

明らかな答えは、 の代わりにRandomthread-unsfae を提供するのと同じように、 のスレッドセーフでないバージョンを提供することです。それは起こりませんでした。それはちょっと奇妙です。その背後にある動機が何であるかはわかりません。java8 では、オブジェクトの一部の int フィールドを直接操作するようにさらに最適化されています。ArrayListVectorThreadLocalRandomThreadLocalRandomThread

于 2013-04-02T14:54:55.857 に答える
1

ThreadLocalRandomのコードはとにかく実装されているThreadLocalようです(あなたが言ったのとまったく同じではありませんが、おそらく十分に近いでしょう)。あなたが持っているものはうまくいくと思います。

于 2013-04-02T13:33:40.867 に答える
0

まず、コードはすべてのスレッドに同じシードを使用します。これはセキュリティ上の問題になる可能性があります。さらに、Random のインスタンスのメンバーへのすべてのアクセスは同期されるため、ThreadLocalRandom の対応するメソッド (同期されていない) よりも遅くなります。Random のインスタンスが現在の Thread をエスケープしないことをコンパイラが確信できる場合、「同期」されたものを最適化することができます。ただし、共有参照を ThreadLocal に格納できるため、コンパイラがこれをチェックする方法はありません。

于 2013-11-29T16:13:59.683 に答える