Dan*_*ani 13 java concurrency multithreading exception
我遇到了ConcurrentModificationException,通过查看它我看不出它为什么会发生的原因; 抛出异常的区域和修改集合的所有位置都被包围
synchronized (this.locks.get(id)) {
...
} // locks is a HashMap<String, Object>;
Run Code Online (Sandbox Code Playgroud)
我试图抓住讨厌的线程,但我可以钉(通过在异常中设置一个断点)是抛出线程拥有监视器而另一个线程(程序中有两个线程)休眠.
我该怎么办?当遇到类似的线程问题时,您通常会做什么?
Ada*_*ter 31
它可能与同步块无关.ConcurrentModificationException
当您在迭代其元素时修改集合时经常会发生这种情况.
List<String> messages = ...;
for (String message : messages) {
// Prone to ConcurrentModificationException
messages.add("A COMPLETELY NEW MESSAGE");
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey 12
与上一篇文章类似,如果删除条目,则可能会出现同样的问题.例如
for(String message : messages) {
if (condition(message))
messages.remove(message);
}
Run Code Online (Sandbox Code Playgroud)
另一个常见的例子是清理地图.
可以使用Iterator明确解决此特定问题.
for(Iterator<String> iter = messages.iterator(); iter.hasNext();) {
String message = iter.next();
if (condition(message))
iter.remove(); // doesn't cause a ConcurrentModificationException
}
Run Code Online (Sandbox Code Playgroud)
有时您的应用程序可能过于复杂而某些功能可能会产生太多副作用.另外,也许另一个线程确实对该列表做错了,你无法轻易找到.
对于我自己的问题,我编写了自己的列表系统,委托另一个列表,一旦锁定,所有其他修改抛出ConcurrentModificationException,因此错误的修改指令将在输出处获得异常.它还可以检测上述错误.
import java.util.*; /** * Created by IntelliJ IDEA. * User: francoiscassistat * Date: 12 juin 2010 * Time: 18:20:18 * * * Lockable list, made to debug ConcurrentModificationException on Lists. * The lock can be switched on/off with setLocked(boolean). * When locked, all write access to the list or iterators gets ConcurrentModificationException. * Simple usage case : * * list.setLocked(true); * * for (Object o : list.iterator()) // now this won't get ConcurrentModificationException, the other instruction that cause this will thrown the exception * { ... } * * list.setLocked(false); */ public class LockableList<E> implements List<E> { protected class LockableListIterator implements Iterator<E> { protected Iterator<E> iterator; public LockableListIterator(Iterator<E> iterator) { this.iterator = iterator; } public boolean hasNext() { return iterator.hasNext(); } public E next() { return iterator.next(); } public void remove() { checkLock(); iterator.remove(); } } protected class LockableListListIterator implements ListIterator<E> { protected ListIterator<E> listIterator; public LockableListListIterator(ListIterator<E> listIterator) { this.listIterator = listIterator; } public boolean hasNext() { return listIterator.hasNext(); } public E next() { return listIterator.next(); } public boolean hasPrevious() { return listIterator.hasPrevious(); } public E previous() { return listIterator.previous(); } public int nextIndex() { return listIterator.nextIndex(); } public int previousIndex() { return listIterator.previousIndex(); } public void remove() { checkLock(); listIterator.remove(); } public void set(E e) { checkLock(); listIterator.set(e); } public void add(E e) { checkLock(); listIterator.add(e); } } protected class LockableListSubList implements List<E> { protected List<E> list; public LockableListSubList(List<E> list) { this.list = list; } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator<E> iterator() { return new LockableListIterator(list.iterator()); } public Object[] toArray() { return list.toArray(); } public <T> T[] toArray(T[] a) { return list.toArray(a); } public boolean add(E e) { checkLock(); return list.add(e); } public boolean remove(Object o) { checkLock(); return list.remove(o); } public boolean containsAll(Collection<?> c) { return list.containsAll(c); } public boolean addAll(Collection<? extends E> c) { checkLock(); return list.addAll(c); } public boolean addAll(int index, Collection<? extends E> c) { checkLock(); return list.addAll(index, c); } public boolean removeAll(Collection<?> c) { checkLock(); return list.removeAll(c); } public boolean retainAll(Collection<?> c) { checkLock(); return list.retainAll(c); } public void clear() { checkLock(); list.clear(); } @Override public boolean equals(Object o) { return list.equals(o); } @Override public int hashCode() { return list.hashCode(); } public E get(int index) { return list.get(index); } public E set(int index, E element) { checkLock(); return list.set(index, element); } public void add(int index, E element) { checkLock(); list.add(index, element); } public E remove(int index) { checkLock(); return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator<E> listIterator() { return new LockableListListIterator(list.listIterator()); } public ListIterator<E> listIterator(int index) { return new LockableListListIterator(list.listIterator(index)); } public List<E> subList(int fromIndex, int toIndex) { return new LockableListSubList(list.subList(fromIndex, toIndex)); } } protected List<E> list; protected boolean locked; public LockableList(List<E> list) { this.list = list; locked = false; } public boolean isLocked() { return locked; } public void setLocked(boolean locked) { this.locked = locked; } protected void checkLock() { if (locked) throw new ConcurrentModificationException("Locked"); } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator<E> iterator() { return new LockableListIterator(list.iterator()); } public Object[] toArray() { return list.toArray(); } public <T> T[] toArray(T[] a) { return list.toArray(a); } public boolean add(E e) { checkLock(); return list.add(e); } public boolean remove(Object o) { checkLock(); return list.remove(o); } public boolean containsAll(Collection<?> c) { return list.containsAll(c); } public boolean addAll(Collection<? extends E> c) { checkLock(); return list.addAll(c); } public boolean addAll(int index, Collection<? extends E> c) { checkLock(); return list.addAll(index, c); } public boolean removeAll(Collection<?> c) { checkLock(); return list.removeAll(c); } public boolean retainAll(Collection<?> c) { checkLock(); return list.retainAll(c); } public void clear() { checkLock(); list.clear(); } @Override public boolean equals(Object o) { return list.equals(o); } @Override public int hashCode() { return list.hashCode(); } public E get(int index) { return list.get(index); } public E set(int index, E element) { checkLock(); return list.set(index, element); } public void add(int index, E element) { checkLock(); list.add(index, element); } public E remove(int index) { checkLock(); return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator<E> listIterator() { return new LockableListListIterator(list.listIterator()); } public ListIterator<E> listIterator(int index) { return new LockableListListIterator(list.listIterator(index)); } public List<E> subList(int fromIndex, int toIndex) { return new LockableListSubList(list.subList(fromIndex, toIndex)); } }
只需使用它:
List list = new LockableList(new ArrayList(...)); list.setLocked(true); for (E e : list.iterator()) { ... } list.setLocked(false);
希望它可以帮助别人.
归档时间: |
|
查看次数: |
16288 次 |
最近记录: |