我正在尝试每5秒更新一次jMapViewer上的标记。在你移动地图之前,这似乎工作得很好。此时它会抛出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());
}
}
感谢您的帮助。
基兰
答案 0 :(得分:0)
您可以使用Semaphore
,Mutex
,监视器(方法签名中包含synchronized
)或锁>来执行此操作strong>(对象上的synchronize
)。存在无锁和等待方法,但这些算法更复杂,仅在特殊情况下才有用。
<强>实施例强>
问题可能是map
同时修改,使用锁,可写:
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());
}
}
这导致只有一个Thread
可以访问map
(如果它运行此代码)。如果一个线程在synchronize
块中,则所有其他线程在块的开头等待。
这种方法的一个问题是所谓的读者 - 写作者问题。大多数数据结构允许多个读者读取,但如果某些线程想要写东西(也修改一些东西),那么 Reader 就不能活性。在这种情况下,使用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();
}
}
您最好使用finally
块,这样即使抛出Exception
,您仍然可以解锁,否则其他任何对象都无法进入关键部分。