我在读取 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();}
1 回答
MM们
TA贡献1886条经验 获得超2个赞
问题不在于日志框架,而在于行
shared.putAll(props);
Properties
类扩展Hashtable
,系统属性可以随时更改。随着shared.putAll(props)
您迭代类的对象props
,Properties(Hashtable)
如果在迭代过程中修改了任何值,我们将得到这个错误ConcurrentModificationException
一个解决方案是在迭代之前在 System.Properties() 对象上调用 clone()
添加回答
举报
0/150
提交
取消