0

私のコードではset、同じリソース上の別の同期ブロック内のリソースで同期ブロックを使用しています。これまでのところ問題は発生していませんが、興味があります。影響がある場合はどうなりますか?これらの同期されたブロックは互いに競合しますか?

Set<myClass> set = Collections.synchronizedSet(new HashSet<myClass>());

synchronized(set) {
    set.add(new myClass());
    ...
    writeSetContentsToFile();
}

public synchronized void writeSetContentsToFile() {
    synchronized(set) {
        ...
    }
}

セットは、他のスレッドによって継続的にアクセスおよび変更されます。同期writeSetContentsToFile()したので、ファイルリソースで競合が発生することはありません。また、内部writeSetContentsToFile()に同期ブロックがあり、反復中にセットに変更が加えられないようにします。

4

3 に答える 3

1

これまでのところ問題は発生していませんが、興味があります。影響がある場合はどうなりますか?

いくつかの方法であなたはあなた自身の質問に答えました、それはうまくいきますが、それは混乱します。可能であれば、コードを単純化するのが最善です。これが可能かどうかを判断するには、コードの残りの部分を調べる必要があります。

于 2012-10-04T13:01:54.593 に答える
1

ここには2つのロックがあります。1つはに、もうthis1つはにありsetます。2つのスレッドが異なる順序でそれらをロックする場合、BANG。デッドロック。すべてのコードを表示していないため、これは不可能かもしれませんが、誰かがクラスを変更して新しいメソッドを追加した場合はどうでしょうか。

Peter Lawreyが言うように、このコードを単純化するようにしてください。

于 2012-10-04T13:20:29.833 に答える
1

あなたの操作がで表現されている場合

synchronized(set) {
    set.add(new myClass());
    ...
    writeSetContentsToFile();
}

アトミックであり、ThreadSafeFileStorableSet専用のメソッド、たとえば、の下で、別のクラスにカプセル化しsynchronized writeContentsToFile()ます。

例えば:

class ThreadSafeFileStorableSet {
    private final Set set;

    ThreadSafeFileStorableSet(Set set) {
        this.set = set;
    }

    synchronized void writeSetContentsToFile() {
        // 
    }

    synchronized void addElements(Object[] elems) {
        // 
    }

    private void doWrite() {
        // use instance set
    }
}

ThreadSafeFileStorableSetクラスの他のすべての非プライベートメソッドsynchronizedも作成して、すべての操作が相互にアトミックになるようにします。synchronized (set)そうすれば、このクラス内にスニペットは必要ありません。

これによりコードが簡素化されますが、同時実行レベルが悪化する可能性があります。しかし、コードを読むことでどれほど悪化する可能性があるかについてアドバイスするのに十分な情報がありません。

于 2012-10-04T13:23:58.067 に答える