java 迭代器 for循环,在并发java应用中使用迭代器for循环

class Nodes has getNodes() method, which is not synchronized. But List nodes - is synchronized. Many threads could be connected to it, changing nodes in it.

Like this:

class Nodes {

List nodes = Collections.synchronizedList(new ArrayList() );

public List getNodes() { return nodes; }

...

}

Client code:

Nodes nodes;

synchronized(nodes) {

for(Node node: nodes.getNodes()) {

...

}

}

I do not have interrogation tests for that, but:

Should I use while(iterator.hasNext()) { var = iterator.next() } instead of for-loop ?

Because I know that when I try to delete nodes.remove(node) inside for-loop it fails with ConcurentModificationException.

EDIT: (related issue)

If iterator is good stuff to use, then having this code (client code):

Iterator iter = nodes.getNodes().iterator();

while (iter.hasNext()) { // line 1

Node node = iter.next(); // line 2

}

It is not safe anyway:

1. thread1 goes to line 1, hoping that now iter would return him next() value.

2. but at that moment thread2 delete that value.

3. thread1 has Exception and fails.

Does it mean that I should do locking on client side anyway. This is what I don't want to do.

One of the solutions I have:

while (iter.hasNext()) {

try {

Node node = iter.next();

...

} catch (NoSuchElementException ex) {continue;} // handle exception - do more try

}

EDIT:

Answer for my case was: to use CopyOnWriteArrayList. I can even stay with for-loop with it.

But another option: Just return client a copy of the list to let them know whatever they want with it. Because it is kind of strange (inconsistent) providing 'snapshot iterator' AND real data in the list at the same time.

解决方案

You should use an iterator like you have suggest, but instead of doing a nodes.delete() (which is really a nodes.remove(...) ) you should instead do iterator.remove()

You have updated your question. Here's an updated answer addressing the 'atomicity' of the iterator. If you want your iterator to have a 'snapshot' of the values at the time it (the iterator) was created, then you can use the Concurrent set of collections in java.util.concurrent: like CopyOnWriteArrayList

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值