移动jMapViewer时的java.util.ConcurrentModificationException
我正在尝试每5秒更新一次jMapViewer上的标记。在您移动地图之前,这似乎工作正常。此时,它抛出一个移动jMapViewer时的java.util.ConcurrentModificationException,java,jmapviewer,Java,Jmapviewer,我正在尝试每5秒更新一次jMapViewer上的标记。在您移动地图之前,这似乎工作正常。此时,它抛出一个java.util.ConcurrentModificationException 我相信这与试图同时访问地图标记列表的不同进程有关,但我不确定如何修复它 timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { loadUnits();
java.util.ConcurrentModificationException
我相信这与试图同时访问地图标记列表的不同进程有关,但我不确定如何修复它
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
loadUnits();
}
}, 5 * 1000, 5 * 1000);
private void loadUnits() {
String query = "SELECT callsign, currentlat,currentlon,previouslat,previouslon, mobile, uniticon FROM unit WHERE isdeleted=0;";
rs = DBase.runQuery(query);
kit.removeAllMapMarkers();
MapMarkerUnit x;
try {
while (rs.next()) {
x = new MapMarkerUnit(rs.getDouble("currentlat"),rs.getDouble("currentlon"));
if (rs.getInt("mobile") == 1) x.setMovement(true);
else x.setMovement(false);
x.setIconName(rs.getString("uniticon"));
x.setPriority(1);
kit.addMapMarker(x);
}
}
catch (SQLException e) {
System.out.print(e.toString());
}
}
谢谢你的帮助
Kieran您可以使用
信号量
,互斥体
,监视器(方法签名中带有同步
)或锁(对象上的同步
)。也存在无锁和无等待的方法,但这些算法更复杂,只在特殊情况下有用
示例 问题可能是
映射
被同时修改,使用锁,可以编写:
synchronize(map) {
map.removeAllMapMarkers();
MapMarkerUnit x;
try {
while (rs.next()) {
x = new MapMarkerUnit(rs.getDouble("currentlat"),rs.getDouble("currentlon"));
if (rs.getInt("mobile") == 1) x.setMovement(true);
else x.setMovement(false);
x.setIconName(rs.getString("uniticon"));
x.setPriority(1);
map.addMapMarker(x);
}
}
catch (SQLException e) {
System.out.print(e.toString());
}
}
这导致只有一个线程
可以访问映射
(如果它运行此代码)。如果一个线程在synchronize
块中,则所有其他线程都在块的开头等待
这种方法的一个问题就是所谓的读者-作者问题。大多数数据结构都允许多个读卡器读取数据,但如果某个线程想要写入某些内容(也要修改某些内容),则任何读卡器都不能处于活动状态。在这种情况下,可以使用ReadWriteLock
:
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public void writeSomething() {
rwl.writeLock().lock();
try {
//Modify/write something
} finally {
rwl.writeLock().unlock();
}
}
public String readSomething() {
rwl.readLock().lock();
try {
//Read something
} finally {
rwl.readLock().unlock();
}
}
您最好使用
最后
块,这样即使抛出异常
,您仍然可以解锁锁,否则其他对象将无法进入关键部分。什么是rs
?你能给出一个MWE吗?RS是一个从MySQL数据库中提取的结果集。对不起,MWE?这有点新。最简单的工作示例,换句话说,代码可以编译和实验…@CommuSoft谢谢-用更多的代码更新了我的问题。我正在看下面的代码——希望在这段代码和谷歌之间,我能够理解它。可能是另一种选择。进一步研究这个问题。map是类jMapViewer的对象。这将在列表中存储地图标记列表。然后,它迭代此操作以重新绘制地图标记。问题似乎是map.removeAllMarkers()会在发生这种情况时删除它们。上面的示例很有意义,但我不确定如何实现它。同步(映射)似乎不起作用,因为迭代器已经在映射中。@KieranS:在这种情况下,您应该在检索标记列表之前锁定map
,只有在不再对该列表执行任何操作时才解锁(结束作用域)。这起作用-在单独的列表上执行操作。谢谢你的帮助和时间@基兰斯:你还应该检查一下,是否每次都会重复这个动作。锁可能导致死锁:两个或多个线程等待对方执行某个操作。