请问是否有任何方法可以在单线程环境中发生并发修改异常,我发布的下面的应用程序包含两个线程,请告诉我在单个线程中也可以看到相同的异常..请指教
package concurrentmodificationError;
import java.util.*;
class ItrDemo
{
public static void main(String arg[])
{
Vector v=new Vector();
v.addElement("Amit");
v.add("Rahul");
v.add(1,"Nitin");
v.addElement("Ankit");
System.out.println("There are "+v.size()+"elements in the vector ");
final Iterator itr=v.iterator();
Thread th=new Thread() {
public void run()
{
System.out.println("New Thread started,traversing elements of vector...");
System.out.println("Contents of vector are...");
while(itr.hasNext())
{
System.out.println(itr.next());
try
{
Thread.sleep(2000);
}
catch(Exception e1)
{
}
}
}
};// end of annomyous class
System.out.println("Suspending main thread and starting a new thread for traversing the contents of vector...");
th.start();
try
{
Thread.sleep(1000);
}
catch(Exception e1)
{
}
System.out.println("main thread resumed,modifying vector...");
v.remove("Ankit");
v.add("Puneet");
v.add("Raman");
System.out.println("Vector Modified , Ankit removed and Puneet & Raman added.");
}
}
是的我得到了人们,在单线程环境中,这个错误可能会出现......如下面的代码所示..
System.out.println("Content of list are : ");
ListIterator itr1=list.listIterator();
while(itr1.hasNext())
{
list.add(new Emp("Anand","Manager",56000)); //
Emp e=(Emp)itr1.next();
e.display();
}
请告知有什么方法可以克服它..所以没有得到这个错误.. !!请指教
答案 0 :(得分:2)
参考ConcurrentModificationException的Javadoc,
请注意,此异常并不总是表示对象具有 由另一个线程同时修改。如果是单线程 发出一系列违反合同的方法调用 一个对象,该对象可能抛出此异常。例如,如果是 线程在迭代时直接修改集合 使用失败快速迭代器进行集合,迭代器将会发生这种情况 异常。
当线程安全集合受并发访问时,并不总是抛出此异常。任何结构修改(添加/删除)都会提示此异常发生。
在您的特定示例中,您正在修改Iterator之外的集合,因此一旦线程从睡眠状态唤醒,它可能会抛出此异常。
答案 1 :(得分:2)
是的,在单线程环境中也可以获得此异常(而不是错误)。 更准确地说,只要当前正在迭代的集合被另一个线程或当前线程修改,就抛出异常。
您遇到此错误的单线程方案示例如下:
Iterator<String> names = namesList.iterator();
while(names.hasNext()){
String currentName = names.next();
if(currentName.startsWith("A")){
namesList.remove(currentName); //here you modify the original collection
}
}
在这种情况下,如果迭代器是一个快速失败的迭代器(正如大多数集合实现所提供的那样),你将得到一个ConcurrentModificationException
答案 2 :(得分:1)
ConcurrentModificationException
。
e.g。
List<String> lst = new ArrayList<String>();
lst.add("sample");
for(String str : lst) {
lst.add("simple");
}
答案 3 :(得分:0)
单个线程中CME的经典示例类似于
List<String> strs = new ArrayList<String>();
strs.add("foo");
strs.add("bar");
for(String str : strs) {
strs.add(str + " added");
}
CME会触发,因为您正在迭代列表并且通过迭代器修改。允许 通过其迭代器修改列表而无需获取CME:
ListIterator<String> strIt = strs.listIterator();
while(strIt.hasNext()) {
String str = strIt.next();
strIt.add(str + " added");
}
// strs now contains "foo", "foo added", "bar", "bar added"
答案 4 :(得分:0)
可以在单个线程环境中抛出ConcurrentModificationException
。只要在不应该在不应该在另一个线程中的上下文中修改对象,就会使用它。
示例:
public class CME {
public static void main(String...args) {
HashSet<Integer> coll = new HashSet<Integer>();
coll.add(1);
coll.add(2);
coll.add(3);
for(Integer i : coll) {
coll.remove(i); // Throws ConcurrentModificationException
}
}
}
答案 5 :(得分:0)
你的问题似乎(对我来说)有点神秘......
关于您的第一个问题,在单线程环境中获取ConcurrentModificationException
,您需要做的就是这样:
List<String> list =...;
for (String str : list)
{
list.remove(str); //this should yield the exception
}
关于你的第二个问题,你发布的代码(有两个主题的代码)很可能会出现这样的异常。到目前为止,由于您拥有的物品数量和超时值,它正在运作。如果你改变这些,你很可能会遇到这种例外。
为避免这种情况,您可以使用synchronized blocks
。通过允许每个线程进行同步部分,通过它可以进行集合修改,您应该能够避免并发修改异常。
您还可以通过使用Semaphore
来管理对列表的访问。