1

同期化された次のコード スニペットはArrayList、マルチスレッド環境で機能しますか?

class MyList {
    private final ArrayList<String> internalList = new ArrayList<String>();

    void add(String newValue) {
        synchronized (internalList) {
            internalList.add(newValue);
        }
    }

    boolean find(String match) {
        synchronized (internalList) {
            for (String value : internalList) {
                if (value.equals(match)) {
                    return true;
                }
            }
        }

        return false;
    }
}

あるスレッドが別のスレッドによる変更を確認できないことが心配です。

4

5 に答える 5

5

コードは機能し、スレッドセーフですが、同時実行ではありません。notnoop および Employmentメソッドのような、または提案されたConcurrentLinkedQueue他の同時スレッドセーフ データ構造の使用を検討することをお勧めします。ConcurrentHashMapCopyOnWriteArraySetcontains

class MyList {
    private final ConcurrentLinkedQueue<String> internalList = 
         new ConcurrentLinkedQueue<String>();

    void add(String newValue) {
        internalList.add(newValue);
    }

    boolean find(String match) {
        return internalList.contains(match);
    }
}
于 2010-01-06T21:54:59.500 に答える
3

これは機能するはずです。これは、同じオブジェクトで同期を行うと、先行発生の関係が確立され、先行読み取りの書き込みが表示されることが保証されるためです。

事前発生の詳細については、Java 言語仕様のセクション 17.4.5を参照してください。

于 2010-01-06T21:52:06.643 に答える
2

List動作しますが、より良い解決策は、を呼び出して を作成することCollections.synchronizedList()です。

于 2010-01-06T21:54:36.007 に答える
2

リストへのすべてのアクセスが同期されるため、問題なく動作します。ただし、CopyOnWriteArrayListロックを回避することで同時実行性を向上させるために使用できます (特に、実行中のスレッドが多数ある場合find)。

于 2010-01-06T21:50:25.147 に答える
0

キーによる検索を行っているため、データに Set(Tree または Hash) を使用することを検討することをお勧めします。それらには、現在の find メソッドよりもはるかに高速なメソッドがあります。

HashSet<String> set = new HashSet<String>();
Boolean result = set.contains(match); // O(1) time
于 2010-01-07T00:45:04.513 に答える