我正在尝试每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());
}
}
谢谢你的帮助。
基兰
最佳答案
您可以使用Semaphore
,Mutex
,监视器(方法签名中带有synchronized
)或锁(对象上的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
块中有一个线程,则所有其他线程在该块的开头等待。这种方法的问题是所谓的“读者-作家”问题。大多数数据结构都允许多个读取器读取,但是如果某个线程想要写入某些内容(也要修改某些内容),则没有任何读取器可以处于活动状态。在这种情况下,使用
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
,您仍然可以解锁该锁,否则其他任何对象将无法进入关键部分。