简体   繁体   English

java.util.ConcurrentModificationException:对哈希图的并发访问

[英]java.util.ConcurrentModificationException: concurrent access to hashmap

In an implementation, i have written the following code. 在一个实现中,我编写了以下代码。 The try-catch block is in a method try-catch块在方法中

try{
    InputVals iv = task.getInputVals();
    Map<String, String> map = iv.getAllValues();
    String a = map.get("value1");
    String b = map.get("value2");
    String x = funcxy.methodGetX();
    String y = funcxy.methodGetY();
    iv.setValue(xval, x);
    iv.setValue(yval,y);

    String []names = {"name1", "name2", "name3"}
    for(int i = 0; i<names.length; i++ ){
         iv.setValue("name"+i, names[i] );
    }
  }

When I make concurrent request few times (not always) it throws "java.util.ConcurrentModificationException: concurrent access to hashmap" error. 当我几次(并非总是)发出并发请求时,会引发“ java.util.ConcurrentModificationException:并发访问哈希图”错误。 I tried using 我尝试使用

Map<String, String> map= new ConcurrentHashMap<String, String>();
map = iv.getAllValues();

But this didnt solve the issue. 但这并不能解决问题。 Can you help me out and let me know where I'm making the mistake. 您能帮助我,让我知道我在哪里犯错。 I cannot change the implementation of 我无法更改

InputVals iv = task.getInputVals();

I'm not entirely sure what you are trying to achieve, but as others have already pointed out, you likely have multiple threads trying to manipulate the map returned by iv.getAllValues() at the same time, hence throwing the exception. 我不确定您要实现的目标,但是正如其他人已经指出的那样,您可能有多个线程试图同时操作iv.getAllValues()返回的映射,从而iv.getAllValues()异常。

Copying the map with a ConcurrentHashMap will work as you would be working off a local copy. 使用ConcurrentHashMap复制地图将像处理本地副本一样工作。 However keep in mind that in doing so, you would be using it locally only, and consequently not need the concurrency checking that it provides. 但是请记住,这样做只会在本地使用它,因此不需要它提供的并发检查。 The problem with your code is that you do not actually copy the data to your new map. 代码的问题是您实际上没有将数据复制到新地图。 You would have needed to do: 您将需要执行以下操作:

Map<String, String> map= new ConcurrentHashMap<String, String>( iv.getAllValues() );

Depending on your needs when making the modifications to the map entries, the simplest & fastest would probably copy the map and work off a local copy. 根据您对地图条目进行修改时的需求,最简单和最快的方法可能是复制地图并进行本地复制。 This will prevent any concurrency issues. 这将防止任何并发问题。 Of course, if the other threads need access to your updated information, this plan does not work. 当然,如果其他线程需要访问您的更新信息,则此计划不起作用。

try{
    InputVals iv = task.getInputVals();
    Map<String, String> map = new HashMap<String, String>();
    // copy all map values to a local var
    map.putAll( iv.getAllValues() );
    String a = map.get("value1");
    String b = map.get("value2");
    String x = funcxy.methodGetX();
    String y = funcxy.methodGetY();
    iv.setValue(xval, x);
    iv.setValue(yval,y);

    String []names = {"name1", "name2", "name3"}
    for(int i = 0; i<names.length; i++ ){
         iv.setValue("name"+i, names[i] );
    }
  }

Short of this, you would need to ensure that any calls to the map are made in synchronized blocks. 简短地说,您需要确保对地图的所有调用均在synchronized块中进行。 However, this can be extremely difficult and tedious if you have several different places in the code where you access this map. 但是,如果您在代码中有多个不同的位置可以访问此地图,则这将非常困难且繁琐。

You have to synchronize all access to the Map returned by the getInputVals(). 您必须同步对getInputVals()返回的Map的所有访问。 It is being altered somewhere in a separate thread. 在单独的线程中的某个地方对其进行了更改。 You will need something along the lines of the code below, but what is also very important is that the lockObj must also be applied everywhere else that this map is being used, including wherever it is currently being modified (this code has not been shown). 您将在下面的代码中需要一些帮助,但是非常重要的一点是,还必须将lockObj应用到使用此映射的其他地方,包括当前正在修改的任何地方(此代码未显示) 。

try{
    InputVals iv = task.getInputVals();
    String a;
    String b;

    synchronized (lockOjb) {
        Map<String, String> map = iv.getAllValues();
        a = map.get("value1");
        b = map.get("value2");
    }
    String x = funcxy.methodGetX();
    String y = funcxy.methodGetY();
    iv.setValue(xval, x);
    iv.setValue(yval,y);

    String []names = {"name1", "name2", "name3"}
    for(int i = 0; i<names.length; i++ ){
         iv.setValue("name"+i, names[i] );
    }
  }

This may or may not be possible, depending on whether you have the ability to change this code. 这是否可能取决于您是否有能力更改此代码。 If it is already happening within a library, for instance, you may simply have to redesign your code so that it is not multithreaded, at least anywhere where this map is accessed. 例如,如果它已经在库中发生,那么您可能仅需重新设计代码,以使它至少在访问此映射的任何地方都不会成为多线程。

What does your InputVals.setValue() does? 您的InputVals.setValue()有什么作用? How is it defined? 如何定义? there is no use if you define ConcurrentHashMap in the business logic as you are using the reference of original variable. 还有,如果你的业务逻辑定义的ConcurrentHashMap为您使用原始变量的引用没有用。 You would need to take care in the actual bean itself. 您需要注意实际的bean本身。

If it some thing like below 如果它像下面这样

Class Inputvals {
  Map<String, String> map = new HashMap <String,String>();
  public void setValue(String a,String b){
    map.put(a,b);
  }
  public Map<String,String> getAllValues(){
    return map;
  }
}

I suggest you to change as below 我建议你改变如下

Class Inputvals {
  Map<String, String> map = new ConcurrentHashMap<String,String>();
  public void setValue(String a,String b){
    map.put(a,b);
  }
  ..
  ...

this should help you to resolve multi threaded access issue. 这应该可以帮助您解决多线程访问问题。

You may need to wrap your map in a Synchronized collection 您可能需要将地图包装在同步集合中

Map<String, String> map = Collections.synchronizedMap(iv.getAllValues());

Then go ahead and access your map. 然后继续访问您的地图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 HashMap java.util.ConcurrentModificationException - HashMap java.util.ConcurrentModificationException 访问hashmap时出现java.util.ConcurrentModificationException - java.util.ConcurrentModificationException while accessing hashmap java.util.concurrent.ExecutionException:java.util.ConcurrentModificationException - java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException 可以更改HashMap的值的成员导致java.util.ConcurrentModificationException - Can changing members of values of HashMap cause java.util.ConcurrentModificationException HashMap迭代/删除获取java.util.ConcurrentModificationException - HashMap iteration/removal getting java.util.ConcurrentModificationException 从HashMap中删除元素时发生异常java.util.ConcurrentModificationException - Exception when removing element from HashMap java.util.ConcurrentModificationException 从哈希图中删除元素时出现 java.util.ConcurrentModificationException - java.util.ConcurrentModificationException when removing elements from a hashmap JAVA java.util.ConcurrentModificationException - JAVA java.util.ConcurrentModificationException Java:java.util.ConcurrentModificationException - Java: java.util.ConcurrentModificationException java.util.ConcurrentModificationException&迭代吗? - java.util.ConcurrentModificationException & iteration?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM