0

3 つのスレッド間の通信用に静的な arrayList を作成したいと考えています。1. スレッドはリストにデータを追加します。2. スレッドはリストからデータを削除します。3. スレッド (3 秒ごとのタイマー) は、リストのサイズが 0 に等しいかどうかをチェックし、そうでない場合は、このリストのすべてのオブジェクトを出力します。

複数のスレッドが同時にこのリストにアクセスしようとするとどうなるか疑問に思っています (たとえば、2 番目のスレッドがリストからオブジェクトを削除するときに、タイマーが同時にリストのサイズをチェックします)。このリストを同期する必要があると思いますが、その方法がわかりません。アドバイスをいただけますか?

4

5 に答える 5

3

複数のスレッドが同時にこのリストにアクセスしようとするとどうなるか疑問に思っています

FirstArrayListスレッドセーフではないため、直接使用しないでください。

1 つの可能性は、Collections.synchronizedList(...);スレッド セーフを提供しますが、同時実行性を妨げるものを使用することです。

あなたの要件は のように見えるので、スレッドセーフなど、そのために使用する必要がありますQueueBlockingQueueLinkedBlockingQueue

ノート:

を使用すると、リストの複合操作は依然として安全ではありませんCollections.synchronizedList(...)

于 2013-10-15T14:17:30.873 に答える
2

使用できます

List myList = Collections.synchronizedList(new ArrayList());
于 2013-10-15T14:16:49.747 に答える
2

ArrayListスレッドセーフではありません。自分で同期を処理する必要があります。そうしないと、結果が予測できなくなります。

関連する質問で示唆されているように:配列リストをスレッドセーフにするにはどうすればよいですCollections.synchronizedList(...)?List

Listjavadoc は、そのメソッドによって返されたを利用する方法の例を示しています。

List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
} 

他のソリューションでは既にこれが提案されていますが、このアプローチを使用すると、同期によって への同時アクセスがブロックされるため、パフォーマンスが低下する可能性がありListます。これにより、バッキングからデータを追加および削除できる速度が最終的に制限されますList

于 2013-10-15T14:17:11.093 に答える
1

このコード スニペットは正しい方向に役立ちます

//have a lock Object
private static final Object lock = new Object();
// your list
private static List list = null

//synchronized on lock object. this will allow only one thread at a time
synchronized(lock){
//access,add to, remove from list
}

このようにして、リストにアクセスするスレッドが一度に 1 つだけであることを確認できます。

于 2013-10-15T14:19:01.293 に答える
1

さらに良いことに、同時実行プリミティブ (待機、通知、および同期) を使用すると、印刷スレッドを待機させ、他のスレッドの 1 つが実際に ArrayList を変更した後にのみウェイクアップすることができます。これには、変更がない場合は印刷せず、変更が発生するとすぐに起動されるという利点があります。依然として偽のウェイクアップが発生する可能性がありますが、問題がある場合はコーディングできます。

印刷スレッドで:

synchronized(lock)
{ 
    while(true/*or some boolean to indicate you're done*/)
    {
        lock.wait();
        //print list
    }
}

リストを編集するスレッドで:

synchronized(lock)
{
    //modify list
    lock.notify();
}

lock.wait(3000);変更が発生しなくても、とにかく 3 秒後に印刷することもできます。

于 2013-10-15T14:32:03.483 に答える