2

たとえば、 a を使用して、特定のスレッドに対して 1 回だけインスタンス化できるクラスがありThreadLocalます。

public class MyClass {
    private static final ThreadLocal<MyClass> classInstance =
        new ThreadLocal<MyClass>() {
            @Override protected MyClass initialValue() {
                return new MyClass();
        }
    };

    private MyClass() {
    }

    public static MyClass getInstance() {
        return classInstance.get();
    }    
}

ここで、これらのスレッド固有のインスタンスに別のスレッドからアクセスできるようにしたいので、そのような解決策になります: https://stackoverflow.com/a/5180323/1768736

この解決策は、スレッド固有の ID (たとえば、 a ) をキーとして使用してMap(私は a に行きます) を使用することです。キーとして使用することを検討していました (スレッド ID を再利用できるという事実に対処するためのメカニズムを提供します)。ConcurrentHashMapMap<long, MyClass>Thread.currentThread().getId()

ただし、このスレッド ID を公開する必要があることを意味します。たとえば、次のようになります。

public class MyClass {
    ...
    public long getId() {
        //return the key associated with this MyClass instance in the Map. 
        //in my case, this would be the ID of the Thread
    }
    public static MyClass getMyClass(long threadId) {
        //allow a Thread to access the MyClass instance of another Thread by providing an ID, 
        //in my case, that would be the Thread ID
    } 
}

だから私の質問は: スレッドの ID (によって返されたものThread.getId()) を公開するのは悪い習慣ですか、それとも心配する必要はありませんか? 理由はわかりませんが、そうすべきではないと腸が教えてくれます。

4

2 に答える 2

3

スレッド ID を使用して (直接) スレッドを強制終了することはできないため、安全に使用できます。アプリケーションはスレッドの作成時にスレッド ID を割り当てることができるため、その使用法は、ログやスレッドダンプなどを見ているときにアプリケーションをデバッグするのに役立つだけだと思います。

また、このリンクで説明されているように、JVM で実行されているスレッドのリストを取得することは難しくありません。スレッドが終了した後にスレッド ID が再利用される可能性があるという事実を認識しており、アプリのロジックがそれを処理する限り、問題はありません。

于 2013-07-06T15:01:31.957 に答える
0

モバイル コードのセキュリティに関心があると思います。それ以外の場合は、脆弱性を導入するようなものではないようです (ID の再利用は非常に長いショットです)。

モバイル コードのセキュリティが心配な場合は、とにかくグローバルおよびスレッド グローバル状態を回避する必要があります。とにかくそうするでしょう。関係なく継続...

セキュリティの観点からはMap、特にキーなどに値以外を使用する場合に問題が発生Threadします。悪意のあるサブクラスは、自分自身と等しくないふりをしたり、別のスレッドと等しいふりをしたり、Threadthrough を取得したりできObject.equals(Object)ます。ここではanIdentityHashMapが理想的ですが、おそらくWeakHashMap. (ではなく でWeakHashMap定義されたキー等価動作を使用する理由がわかりません。 A (「星図」) が優れているでしょう。)MapIdentityHashMapConcurrentWeakIdentityHashMap

を変更せずThreadに、必要な動作を提供するスレッドをラップするキー オブジェクトを導入することをお勧めします。

final class Key {
    private final int hash;
    private final WeakReference<Thread> ref;
    public Key(Thread thread) {
        this.hash = System.identityHashCode(thread);
        this.ref = new WeakReference<Thread>();
    }
    @Override public int hashCode() {
        return hash;
    }
    @Override public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Key)) return false;
        Key other = (Key)obj;
        Thread thread = this.ref.get();
        return thread != null && thread == other.ref.get(); 
    }
}

(エントリを削除できるように、参照をキューに入れたいと思うでしょう。)

Thread.getAllStackStracesにはセキュリティ チェックがあるため、信頼されていないコードがそれらすべてを取得することはできません。同様の呼び出しは、実行をアクセス可能なスレッド グループに制限します。

于 2013-07-08T12:06:42.110 に答える