Collections.synchronizedListの使用方法
3713 ワード
ArrayList
ArrayListは非スレッドで安全であることはよく知られているが、マルチスレッドの場合、リストにデータを挿入する場合、データが失われるおそれがある.一方のスレッドがListを巡回する、他方のスレッドがListを修正すると、ConcurrentModificationException(同時修正異常)エラーが報告される.
Vector
Vectorはスレッドの安全なリストであるが、そのスレッドの安全な実現方式はすべての操作にsynchronizedキーワードを加えたものであり、効率に深刻な影響を及ぼす.従って、Vectorの使用は推奨する.
Collections.synchronizedList(List list)
リストのスレッドセキュリティを実現するにはCollectionsを使用します.synchronizedList、まずその使い方を見てみましょう.
使用方法
なぜadd()はsynchronizedを必要とせず、遍歴するときにsynchronizedを追加する必要があるのですか?
まずCollectionsを見てみましょうsynchronizedListのソースコード
Collections.synchronizedListのソースコード
この方法は、あなたが入力したListがRandomAccessというインタフェースを実装するかどうかによって返されるSynchronizedRandomAccessListかSynchronizedListかを返します.
次にSynchronizedListのソースコードを見てみましょう
SynchronizedListソースコード
add()などのメソッドを実行する際にsynchronizedのキーワードが付けられていることがわかるが、listIterator()、iterator()は付けていない.だから使用するときはsynchronizedを加える必要があります.
ArrayListは非スレッドで安全であることはよく知られているが、マルチスレッドの場合、リストにデータを挿入する場合、データが失われるおそれがある.一方のスレッドがListを巡回する、他方のスレッドがListを修正すると、ConcurrentModificationException(同時修正異常)エラーが報告される.
Vector
Vectorはスレッドの安全なリストであるが、そのスレッドの安全な実現方式はすべての操作にsynchronizedキーワードを加えたものであり、効率に深刻な影響を及ぼす.従って、Vectorの使用は推奨する.
Collections.synchronizedList(List list)
リストのスレッドセキュリティを実現するにはCollectionsを使用します.synchronizedList、まずその使い方を見てみましょう.
使用方法
List list = Collections.synchronizedList(new ArrayList());
list.add("1");
list.add("2");
list.add("3");
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext()) {
//foo(i.next());
System.out.println(i.next());
}
}
なぜadd()はsynchronizedを必要とせず、遍歴するときにsynchronizedを追加する必要があるのですか?
まずCollectionsを見てみましょうsynchronizedListのソースコード
Collections.synchronizedListのソースコード
public static List synchronizedList(List list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
この方法は、あなたが入力したListがRandomAccessというインタフェースを実装するかどうかによって返されるSynchronizedRandomAccessListかSynchronizedListかを返します.
次にSynchronizedListのソースコードを見てみましょう
SynchronizedListソースコード
static class SynchronizedList
extends SynchronizedCollection
implements List {
private static final long serialVersionUID = -7754090372962971524L;
final List list;
SynchronizedList(List list) {
super(list);
this.list = list;
}
SynchronizedList(List list, Object mutex) {
super(list, mutex);
this.list = list;
}
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {return list.equals(o);}
}
public int hashCode() {
synchronized (mutex) {return list.hashCode();}
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
public int indexOf(Object o) {
synchronized (mutex) {return list.indexOf(o);}
}
public int lastIndexOf(Object o) {
synchronized (mutex) {return list.lastIndexOf(o);}
}
public boolean addAll(int index, Collection extends E> c) {
synchronized (mutex) {return list.addAll(index, c);}
}
public ListIterator listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}
public List subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedList<>(list.subList(fromIndex, toIndex),
mutex);
}
}
@Override
public void replaceAll(UnaryOperator operator) {
synchronized (mutex) {list.replaceAll(operator);}
}
@Override
public void sort(Comparator super E> c) {
synchronized (mutex) {list.sort(c);}
}
... ...
}
add()などのメソッドを実行する際にsynchronizedのキーワードが付けられていることがわかるが、listIterator()、iterator()は付けていない.だから使用するときはsynchronizedを加える必要があります.