您的位置:首页 > 编程语言 > Java开发

java.util.ConcurrentModificationException

2015-09-09 09:18 483 查看
最近一次系统内存泄漏,排查发现是一个框架的清资源的线程异常退出导致的,退出的原因就是抛出了ConcurrentModificationException。

何时抛ConcurrentModificationException?

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

这个解释其实挺不清楚的,什么叫做没有权限时的修改啊,哪些情况啊。目前所知的是对Collection 遍历时的修改要特别注意。
http://stackoverflow.com/questions/8189466/java-util-concurrentmodificationexception
抛异常代码如下:

static
{
Thread th = new Thread("ShyCacheScanThread"){
public void run()
{
while( true )
{
try{ Thread.sleep(DEFAULT_CHECK_INTERVAL); }catch(InterruptedException e){}
synchronized( ALL_CACHE )
{
for( AbstractCache cache : ALL_CACHE )
{
int x = Math.min(cache.mCapacity/2,cache.mMap.size()-cache.mCapacity);
if( x > 0 )
cache.evict(x);
}
}
}
}
};
th.setDaemon(true);
th.start();
}


其中ALL_CACHE是一个List对象,其实这段代码没有什么问题,只是对ALL_CACHE做了遍历,但是这里要特别小心的是,在修改这个对象的其他地方也必须加锁才行,但是不幸的是

public AbstractCache(int capacity)
{
if( capacity <= 0 )
throw new IllegalArgumentException("capacity <= 0");
mCapacity = capacity;
mMap = new IntHashMap(capacity);
ALL_CACHE.add(this);
}


在此处对ALL_CACHE的修改并没有加锁,一旦构造AbstractCache时,ShyCacheScanThread在遍历,那异常就抛出来了。

解决方法就是在add处也加上ALL_CACHE对象的锁,但是并不是很优雅。另我不解的是为啥框架的cache实现要这样子,唉~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: