13.新たに追加されたコレクション32006.06.21 株式会社四次元データ 宮澤了祐
ユーティリティ 13章 新たに追加されたコレクション3
13.1. ConcurrentMapMapを拡張して次のメソッドを加えています。
concurrentパッケージにConcurentMapを実装したクラスjava.util.concurrentHashMapがあります。 反復子の取得のために、全体をロックする必要はありません。 更新を防ぐ必要のないアプリケーションで、同期化したCollections.synchronizedMapの代わりなどに使われます。 反復子での値の取得は、その時点において完了している変更を反映します。 {
Map map = new ConcurrentHashMap();
...
Thread thread = new Thread(new MyRunnable(map));
thread.start();
map.remove("value");
...
}
public void run() {
Iterator itr = map.values().iterator();
while(itr.hasNext()){
System.out.println(itr.next());
try{
Thread.sleep(1000);
}catch(InterruptedException e){
}
}
}
上記の様に反復子取得中に要素を削除したとしてもConcurrentModificationExceptionを投げることはありません。 ただし反復子取得中の要素変更が反映されることは保証されているわけではありません。 13.2. CopyOnWriteArrayListjava.util.ArrayListをスレッドセーフにした実装です。 import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
public class MyCopyOnWriteArrayList implements Runnable{
public static void main(String[] args){
CopyOnWriteArrayList array = new CopyOnWriteArrayList();
array.add(0,0);
array.add(1,1);
array.add(2,2);
array.add(3,3);
array.add(4,4);
Thread thread = new Thread(new MyCopyOnWriteArrayList(array));
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(5 + "を追加しました。");
array.add(5,5);
System.out.println(4 + "を削除しました。");
array.remove(4);
}
public MyCopyOnWriteArrayList(CopyOnWriteArrayList array){
this.array = array;
}
public void run(){
Iterator itr = array.iterator();
int i=0;
while(itr.hasNext()){
System.out.println(i + ":" + itr.next());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
これは次のように出力されます。 0:0 5を追加しました。 4を削除しました。 0:1 0:2 0:3 0:4 反復子作成後の状態が反映されていないのがわかります。 13.3. CopyOnWriteArraySetスレッドセーフなjava.util.Setです。 import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
public class MyCopyOnWriteArraySet implements Runnable{
CopyOnWriteArraySet set;
public MyCopyOnWriteArraySet(CopyOnWriteArraySet set) {
this.set = set;
}
public static void main(String[] args) {
CopyOnWriteArraySet set = new CopyOnWriteArraySet();
set.add(0);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
Thread thread = new Thread(new MyCopyOnWriteArraySet(set));
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(5 + "を追加しました。");
set.add(5);
System.out.println(3 + "を削除しました。");
set.remove(3);
}
public void run() {
Iterator itr = this.set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
次のように出力されます。 0 5を追加しました。 3を削除しました。 1 2 3 4 反復子作成後の変更が反映されていないことがわかります。 |
![]()
![]()
|