我在下面有这个代码,我通过执行以下行得到一个ConcurrentModificationException:
filterCardsToDevice(getCollection());
Run Code Online (Sandbox Code Playgroud)
代码:
private List<MyClass> filterCardsToDevice(Collection<MyClass> col) {
final List<MyClass> newList = new ArrayList<MyClass>();
for (MyClass myObj : col) {
long id = myObj.getId();
if (id < 0 || id > 0xFFFFFFFFl) {
// just a log here
} else {
newList.add(myObj);
}
}
return newList;
}
private final Map<Long, MyClass> map = new HashMap<Long, MyClass>();
public Collection<MyClass> getCollection() {
synchronized (map) {
return Collections.unmodifiableCollection(map.values());
}
}
Run Code Online (Sandbox Code Playgroud)
堆栈是:
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)
at java.util.HashMap$ValueIterator.next(HashMap.java:871)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
Run Code Online (Sandbox Code Playgroud)
正好在foreach线上:
for (MyClass myObj : col) …Run Code Online (Sandbox Code Playgroud) 按照Sun,
"Iterator.remove是在迭代期间修改集合的唯一安全方法;如果在迭代进行过程中以任何其他方式修改基础集合,则行为未指定."
我有两个问题:
我知道如果使用迭代器在某个线程遍历它时将更改Collection,则iterator.next()将抛出ConcurrentModificationException.
但它根据列表中的元素数量显示不同的行为.
我尝试了一个代码片段,在其中遍历for-each循环中的列表,在它之间,遍历使用列表的remove()方法从列表中删除了一个元素.
理想情况下,它应该在此条件下抛出ConcurrentModificationException而不依赖于列表中的元素数量,但是当列表中的元素数量为2时,它不是真的.
案例1: 列表中的元素数量 - 1
public static void main(String[] args)
{
List<String> list=new ArrayList<String>();
list.add("One");
for (String string : list)
{
System.out.println(string);
list.remove(string);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:一
线程"main"java.util.ConcurrentModificationException中的异常
这是预期的.
案例2:列表中的元素数量 - 2
public static void main(String[] args)
{
List<String> list=new ArrayList<String>();
list.add("One");
list.add("two");
for (String string : list)
{
System.out.println(string);
list.remove(string);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:一
没有例外被抛出?????????
案例3:列表中的元素数量 - 3
public static void main(String[] args)
{
List<String> list=new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
for (String string …Run Code Online (Sandbox Code Playgroud) 我有Android多线程应用程序.
两个或更多触发器有可能运行相同的代码部分.
我有一个对象列表.
我让它同步了 Collections.synchronizedList
private List<WmGroupItemSample> mGroupItemSampleList;
mGroupItemSampleList = new ArrayList<WmGroupItemSample>();
mGroupItemSampleList = Collections.synchronizedList(mGroupItemSampleList);
Run Code Online (Sandbox Code Playgroud)
但有时我会在线获得Exception:
Collections.sort(mGroupItemSampleList, new GroupItemSampleComparator());
Run Code Online (Sandbox Code Playgroud)
java.util.ConcurrentModificationException
at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:62)
at java.util.Collections.sort(Collections.java:1895)
Run Code Online (Sandbox Code Playgroud)
Collections.synchronizedList不阻止此异常?[编辑]
GroupItemSampleComparator
public class GroupItemSampleComparator implements java.util.Comparator<WmGroupItemSample> {
public GroupItemSampleComparator() {
super();
}
public int compare(WmGroupItemSample s1, WmGroupItemSample s2) {
return ( (s2.getStartDate() - s1.getStartDate()) > 0 ) ? (-1) : (1);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
我希望迭代一个集合,但集合的内容将在迭代期间修改.我希望在创建迭代器时迭代原始集合,而不是迭代添加到集合中的任何新元素.这怎么可能?这是set的默认行为还是我该如何实现?
我能想到的一种方法是从原始集合中获取一个不会被修改的新集合,但这看起来不够优雅并且必须有更好的解决方案.
好的,我在这里要做的是让一个方法"运行"一个给定数量的"时间"的过程,这个所有接缝在一定程度上工作,但它不断给出这些例子.这是它给出的第一个执行
Exception in thread "main" java.util.ConcurrentModificationException
Run Code Online (Sandbox Code Playgroud)
然后在exicutio它给出了这个
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at parta.PartA.runQueueOne(PartA.java:273)
Run Code Online (Sandbox Code Playgroud)
我不知道我在做什么错在这里我应该让这个并发或什么?如果是这样的话?我认为链表本质上是同步的?也许那就是我搞砸了.
那么这里的任何方式是我使用的方法:
public static void runQueueOne(LinkedList<MyProcess> q1, LinkedList<MyProcess> q2, LinkedList<MyProcess> q3, LinkedList<MyProcess> q4, int ct)
{
System.out.println("Running Level One Queue");
for(MyProcess p : q1)
{
if(p.name.equalsIgnoreCase(q1.getFirst().name))
{
//add 3 millsedonds to the service time
q1.getFirst().serviceTimeTotal += 3;
System.out.println(q1.getFirst().name + " is running");
}else
{
//add 3 millseconds to wait time fr the un busy one
p.waitTimeTotal+=3;
}
}
for(MyProcess p : q2)
{
p.waitTimeTotal+=3;
}
for(MyProcess p …Run Code Online (Sandbox Code Playgroud) 我必须处理一个 Map <BitSet,List<List<Integer>> MyMap
if (key1 contains all of corresponding true bits of key2)
Remove from key2 all those values which are common with key1)
Run Code Online (Sandbox Code Playgroud)
在此过程中,如果列表中的元素数量低于THRESHOLD(用户定义的正整数),则将其删除.此外,如果Map包含空列表,则删除相应的键.
我使用以下代码:
List<BitSet> keys = new ArrayList<>(MyMap.keySet());
ListIterator it1=keys.listIterator();
while(it1.hasNext()) {
BitSet key1=(BitSet)it1.next();
ListIterator it2=keys.listIterator(it1.nextIndex());
while(it2.hasNext()) {
BitSet key2=(BitSet)it2.next();
BitSet ankey=(BitSet)key1.clone();
ankey.and(key2);
if(ankey.equals(key1)) {//key1 is subset and key2 is superset
if(removePoints(key1,key2)) {
it1.remove();
break;
}
}
else if(ankey.equals(key2)) {
if(removePoints(key2,key1)) {
it2.remove();
}
}
}
}
public static boolean removePoints(BitSet key1,BitSet key2)
{
List<List<Integer>> list1=MyMap.get(key1); …Run Code Online (Sandbox Code Playgroud) 在HashMap中
map = new HashMap<String,String>();
it = map.entrySet().iterator();
while (it.hasNext())
{
entry = it.next();
it.remove(); //safely remove a entry
entry.setValue("new value"); //safely update current value
//how to put new entry set inside this map
//map.put(s1,s2); it throws a concurrent access exception
}
Run Code Online (Sandbox Code Playgroud)
当我试图添加一个新的条目来映射它抛出ConcurrentModificationException.对于删除和更新,迭代器已安全地删除方法.如何在迭代时添加新条目?
我正在阅读这个" Freuqent Java并发问题 "的问题,并且在谈论java.util.ConcurrentModificationException的答案时感到困惑.
我对答案的理解是,这可能发生在单线程程序中.如何或什么条件导致以下代码抛出异常?
List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));
for (String string : list) { list.remove(string); }
Run Code Online (Sandbox Code Playgroud) 我正在使用ThreadSafeList,因为它将数据从进程流式传输到Web服务器,然后在将数据传入客户端时将数据流回流,因此我获得了很大的收益.在内存中我使用Spring Caching(引擎盖下的ehcache)将数据保存在JVM中,一切都很顺利.当我开始达到我的堆限制并且Spring Caching在我使用它时将我的ThreadSafeList序列化到磁盘时,麻烦就开始了,导致了ConcurrentModificationExceptions.我可以覆盖Serialization接口的私有writeObject和readObject方法来解决问题吗?我不确定如何做到这一点或我是否应该放弃我的ThreadSafeList.
回到我开始这个程序的时候,我使用的是BlockingDeque,但这还不够,因为当我放置并采用结构时,我记不起用于缓存的数据......我不能使用ConcurrentMap因为我需要订购在我的列表中...我应该去ConcurrentNavigableMap吗?我想用ThreadSafeList滚动自己,自定义私有序列化功能可能是浪费?
java multithreading java.util.concurrent concurrentmodification spring-cache
java ×10
iterator ×5
collections ×3
asynchronous ×1
concurrency ×1
hashmap ×1
linked-list ×1
list ×1
set ×1
spring-cache ×1
unmodifiable ×1