猿问

从属性文件读取时出现 java.util.ConcurrentModifi

我在读取 JVM 配置属性时遇到了问题,System.getProperties()因为在某些环境中我java.util.ConcurrentModificationException在 JVM 重新启动后遇到了问题。

[err] java.util.ConcurrentModificationException [err] at java.util.Hashtable$Enumerator.next(Hashtable.java:1502)

为了避免前面提到的错误,我必须多次重新启动 VM。

到目前为止我做了什么:

  • 同步属性键和值被读取和写入日志文件的方法;

  • 因为 Java 的 Properties 对象是一个 HashMap,所以我尝试使用同步 Map;

  • 我试图通过使用更多共享相同 Properties 对象的线程来模拟并发问题,但是我无法在本地环境中重现该错误;

  • 由于线程安全,我正在使用 StringBuffer;

private static final Logger LOG = LoggerFactory.getLogger(PropertyLogger.class);

public static synchronized final void logProperties() {

        Level oldLevel = LOG.getLevel();

        LOG.setLevel(Level.INFO);

        Properties props = System.getProperties();

        Map<Object, Object> shared = Collections.synchronizedMap(new HashMap<>());

        shared.putAll(props);


        for (final Entry<Object, Object> entry : shared.entrySet()) {

          try{  StringBuffer buffer = new StringBuffer();

            buffer.append(entry.getKey());

            buffer.append(" = "); //$NON-NLS-1$

            buffer.append(entry.getValue());

            LOG.info(buffer.toString());

          }

          catch (Exception ex){

              ex.printStackTrace();

          }

        }

        LOG.setLevel(oldLevel);


    }

我可能是我正在处理的问题也由用于编写的 log4j 库触发,我知道这不是线程安全的。


我添加了堆栈跟踪:


[err] java.util.ConcurrentModificationException [err] at java.util.Hashtable$Enumerator.next(Hashtable.java:1502) [err] at com.myapp.common.PropertyLogger.logProperties(PropertyLogger.java:23) [err] ] 在 com.myapp.input.ConfigurationServer.parse(ConfigurationServer.java:710) [err] 在 com.myapp.input.ConfigurationServer.configure(ConfigurationServer.java:94) [err] 在 com.myapp.input.Application。运行(Application.java:78)[err] 在 com.myapp.input.servlet.InputStarter$ValidatorThread.run(InputStarter.java:113)


问候,


PS:我应该添加同步块来调用方法吗?例如:在 parse 方法中应该调用我的代码


synchronized(this) {

     PropertyLogger.logProperties();

}


手掌心
浏览 142回答 1
1回答

MM们

问题不在于日志框架,而在于行shared.putAll(props);Properties类扩展Hashtable,系统属性可以随时更改。随着shared.putAll(props)您迭代类的对象props,Properties(Hashtable)如果在迭代过程中修改了任何值,我们将得到这个错误ConcurrentModificationException一个解决方案是在迭代之前在 System.Properties() 对象上调用 clone()
随时随地看视频慕课网APP

相关分类

Java
我要回答