我在讀取 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
提交
取消