Opened 11 years ago
Last modified 11 years ago
#10674 closed defect
ConcurrentModificationException when addind multiple marker — at Version 3
| Reported by: | Owned by: | The111 | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | JMapViewer | Version: | latest |
| Keywords: | ConcurrentModificationException addMapMarker | Cc: |
Description (last modified by )
I am using a for loop to add markers about hotels to my map. But I am getting a ConcurrentModificationException when addind multiple marker.
this is the stack trace:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(Unknown Source) at java.util.LinkedList$ListItr.next(Unknown Source) at org.openstreetmap.gui.jmapviewer.JMapViewer.paintComponent(JMapViewer.java:629) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintToOffscreen(Unknown Source) at javax.swing.BufferStrategyPaintManager.paint(Unknown Source) at javax.swing.RepaintManager.paint(Unknown Source) at javax.swing.JComponent._paintImmediately(Unknown Source) at javax.swing.JComponent.paintImmediately(Unknown Source) at javax.swing.RepaintManager$4.run(Unknown Source) at javax.swing.RepaintManager$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.access$1300(Unknown Source) at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$400(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
Here is the code :
for(int i=0; i < len; i++){ hotel = hotelsList.getJSONObject(i); lat = hotel.getDouble("lat"); lng = hotel.getDouble("lng"); name = hotel.getString("name"); JMAP.addHotel(lat, lng, name); }
and this is the addHotel method in JMAP class:
public static void addHotel(double lat, double lng, String name){ map.addMapMarker( new MapMarkerDot(name, new Coordinate(lat,lng))); }
JMAP is a class created from the DEMO class you offer.
Change History (3)
comment:1 by , 11 years ago
| Priority: | major → minor |
|---|---|
| Type: | defect → enhancement |
comment:2 by , 11 years ago
| Priority: | minor → normal |
|---|---|
| Type: | enhancement → defect |
The problem is in the JMapViewer code:
mapMarkerList is looped over in JMapViewer.paintComponent, which runs in EDT. Now if JMapViewer.addMapMarker modifies this list from another thread while the painting operation is in progress, you get ConcurrentModificationException.
There are several ways to solve this, probably the simplest is:
mapMarkerList = Collections.synchronizedList(new LinkedList<>());
Then you still need to synchronize non-atomic operations like list iteration:
synchronized(mapMarkerList) { for (MapMarker marker : mapMarkerList) { if(marker.isVisible())paintMarker(g, marker); } }
Also I would make a copy and return a copy in setMapMarkerList and getMapMarkerList.
comment:3 by , 11 years ago
| Description: | modified (diff) |
|---|



There is no issue with standard JMapViewer and adding multiple map markers by the intended procedure. The demo already has many markers on it! And it is very easy to add a few more. Adding these lines to Demo.java:
map().addMapMarker(new MapMarkerDot("dot1", new Coordinate(1, 1))); map().addMapMarker(new MapMarkerDot("dot2", new Coordinate(2, 2))); map().addMapMarker(new MapMarkerDot("dot3", new Coordinate(3, 3))); map().addMapMarker(new MapMarkerDot("dot4", new Coordinate(4, 4)));We can see them on the panel at runtime easily.
http://i.imgur.com/zYulHJ6.png
Somehow you are attempting to concurrently modify the backing list. Admittedly this should probably be prevented through public accessible methods. Please post a snapshot of your current codebase, otherwise it is impossible to say how you're doing this.