2014-09-02 2 views
1

매 5 초마다 jMapViewer에서 마커를 업데이트하려고합니다. 이것은지도를 이동할 때까지 제대로 작동하는 것 같습니다. 이 시점에서 java.util.ConcurrentModificationException을 던집니다.java.util.ConcurrentModificationException 이동 중 jMapViewer

저는 이것이지도 마커 목록에 동시에 액세스하려는 여러 프로세스와 관련이 있다고 생각하지만 해결 방법을 모르겠습니다.

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()); 
    } 
} 

도움 주셔서 감사합니다.

키에 란은

+1

'rs'란 무엇입니까? MWE를 줄 수 있습니까? –

+0

RS는 MySQL 데이터베이스에서 가져온 ResultSet입니다. 미안 MWE? 이것에 조금 새로운. – KieranS

+0

최소 작업 예제, 다른 말로하면 하나의 코드를 컴파일하고 실험 할 수 있습니다. –

답변

0

당신이이 Semaphore, Mutex을 사용하여 (메소드 서명에 synchronized 포함) 모니터 또는 잠금 (객체에 synchronize를) 할 수 있습니다. lock-free대기가 있습니다. 접근 방식도 있지만 이러한 알고리즘은 더욱 복잡하며 특별한 상황에서만 유용합니다.


문제는 아마 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()); 
    } 
} 

을이 사실에 결과를 하나의 Threadmap에 액세스 할 수 있습니다 (이 코드를 실행하는 경우). 한 스레드가 synchronize 블록에 있으면 다른 모든 스레드는 블록 시작 부분에서 대기합니다.

이 접근법의 문제점은 독자 - 작성자 문제입니다. 대부분의 데이터 구조는 복수로 읽을 수 있습니다 독자가인데 어떤 경우 스레드 무언가를 쓰고 싶다면 (아무 것도 수정해도됩니다), 리더이 활성화 될 수 있습니다. 이 경우 하나를 사용하는 ReadWriteLock : Exception가 발생하더라도 여전히 잠금을 해제하도록 당신은 더 나은, finally 블록을 사용

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(); 
    } 
} 

그렇지 않으면 다른 개체가 임계 영역를 입력 할 수 없습니다.

+0

이 문제를 자세히 살펴보십시오. map은 jMapViewer 클래스의 객체입니다. 이렇게하면지도 마커 목록이 목록 에 저장됩니다. 그런 다음지도 마커를 다시 그리기 위해이 과정을 반복합니다. 이 문제가 발생하는 동안 map.removeAllMarkers()를 제거하는 문제가 나타납니다. – KieranS

+0

위의 예는 의미가 있지만 구현 방법을 잘 모르겠습니다.반복기가 이미지도 내부에 있으므로 동기화 (지도)가 작동하지 않는 것 같습니다. – KieranS

+0

@KieranS :이 경우 마커 목록을 검색하기 전에'map'을 잠 가야하며 더 이상 해당 목록에 대해 아무런 작업도 수행되지 않으면 잠금 해제 (범위 끝내기) 만하십시오. –

관련 문제