这是防止 ConcurrentModificationException 的好方法吗
另一个问题是关于同步的。我在 Note 类中还有一个 run() ,因为我想每 5 分钟输出一次 Notes 中的每个元素。但如果我尝试在 main 中进行更多会议,我总是会遇到异常:java.util.ConcurrentModificationException。所以我应用程序同步到列表笔记,当我迭代笔记时,可能会添加一个新会议。我的运行方法如下:
列表笔记上的同步以防止 ConcurrentModificationException 的正确方法是否正确?(在我的程序它可以工作。我现在从来没有遇到过这个异常)
会议类和注释类可能喜欢这样:
public class Meeting{
public Meeting(Note note_1,Note note_2){
note_1.addElement(this);
note_2.addElement(this);}
//another method hier
}
public class Note implements Runnable{
public final List<Meeting> notes = new ArrayList<Meeting>();
public void addElement(Meeting n){
entries.add(n);
}
@Override
public void run(){
while(true) {
for(Meeting n : notes){
System.out.println(n.toString);}
}
try{ Thread.sleep(10);}
}
}
}
如果我尝试在main ,所以我在类 Note 中更改了一点,喜欢这个:
private static final List<Entry> entries = Collections.synchronizedList(new ArrayList<Entry>());
在 run()
@Override
public void run() {
while(true){
synchronized(notes){
for(Entry n : entries){
//do something
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e ) {
}
}
}
}
The another question is about synchronized. I have also a run() in class Note,because i want to output each element in notes every 5 minutes. But i get always exception:java.util.ConcurrentModificationException,if i try to make more meetings in main. so i applay synchronized to the list notes which may be added a new meeting when i iterate over notes.My run method like this:
Is it correct way hier on list notes to synchronized to prevent ConcurrentModificationException ?(In my program it works.I get never this exception now)
A Meeting class and Note class may likes this:
public class Meeting{
public Meeting(Note note_1,Note note_2){
note_1.addElement(this);
note_2.addElement(this);}
//another method hier
}
public class Note implements Runnable{
public final List<Meeting> notes = new ArrayList<Meeting>();
public void addElement(Meeting n){
entries.add(n);
}
@Override
public void run(){
while(true) {
for(Meeting n : notes){
System.out.println(n.toString);}
}
try{ Thread.sleep(10);}
}
}
}
I get always exception error about exception:java.util.ConcurrentModificationException if i try to make more Meeting in main ,So i changes a littel in class Note,likes this :
private static final List<Entry> entries = Collections.synchronizedList(new ArrayList<Entry>());
and in run()
@Override
public void run() {
while(true){
synchronized(notes){
for(Entry n : entries){
//do something
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e ) {
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自 javadoc
请注意,此异常并不总是表明对象已被不同线程同时修改。如果单个线程发出一系列违反对象约定的方法调用,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
这意味着即使在同一线程中,也不要在循环中更改集合并同时迭代它。
From the javadoc
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will thow this exception.
THis means do not change your collection in a loop and iterate over it at the same time even in the same thread.
阅读@Navi 所写的内容。
简而言之 - 永远不要在每个循环中删除/添加集合的元素。
我曾经遇到过此类问题,因此决定使用 http://code.google.com/ p/google-collections/
那里有一些映射/过滤函数(如果我记得这些方法在 Collections2 库中)。
如果您不愿意把事情做对,您可以随时使用老式的迭代器技术。
Read to what @Navi had written.
In a nutshell - NEVER remove/add elements of a collection in for each loop.
I once had that kind of problem and I decided to use http://code.google.com/p/google-collections/
There are some map/filter functions there (if I recall that methods were in Collections2 library).
If you are not willing to make the things right, you can always use the old-school iterator technique.
我之前使用过 CopyOnWriteArrayList当我遇到此类问题时。
这会为每次写入生成底层数组的完整副本,因此效率不是很高,但我发现它对于特定情况非常有用(例如,管理向某些其他类发出的专门事件通知的类)
I've used a CopyOnWriteArrayList before when I encountered this sort of problem.
This makes a complete copy of the underlying array for each write, so it's not very efficient, but I've found it very useful for specific circumstances (e.g. a class which manages specialised event notification to some other classes)