ConcurrentModificationException은 허용되지 않는 객체를 동시에 수정하려고 할 때 발생합니다. 이 예외는 일반적으로 작업할 때 발생합니다. Java 컬렉션 클래스 .
예를 들어 - 다른 스레드가 컬렉션을 반복할 때 스레드가 컬렉션을 수정하는 것은 허용되지 않습니다. 이는 반복 결과가 정의되지 않기 때문입니다. JRE에서 제공하는 Iterator의 모든 범용 구현을 포함하여 Iterator 클래스의 일부 구현에서 이 예외가 발생합니다. 이를 수행하는 반복자를 호출합니다. 빠른 실패 미래에 언제든지 컬렉션의 결정되지 않은 동작에 직면하는 대신 그러한 상황이 발생하자마자 신속하게 예외를 발생시키기 때문입니다.
RDBMS
메모:다른 스레드가 Collection 객체를 수정하려고 할 때만 이 예외가 발생하는 것이 필수는 아닙니다. 단일 스레드에 개체 계약을 위반하려고 하는 일부 메서드가 호출되는 경우에도 발생할 수 있습니다. 이는 스레드가 일부 개체에 의해 반복되는 동안 컬렉션 개체를 수정하려고 할 때 발생할 수 있습니다.빠른 실패 반복자, 반복자는 예외를 발생시킵니다.
예
import java.awt.List; import java.util.*; public class Concurrentmodificationexception { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator it = list.iterator(); while (it.hasNext()) { Integer value = it.next(); System.out.println('List Value:' + value); if (value.equals(3)) list.remove(value); } } }
산출:
이 메시지는 반복자가 목록을 반복하고 동시에 수정하기 때문에 다음 메서드가 호출될 때 예외가 발생한다는 것을 나타냅니다. 그러나 아래와 같이 해시맵을 수정하면 해시맵의 크기가 변경되지 않으므로 예외가 발생하지 않습니다.
문자열의 Java int
예를 들어-
import java.awt.List; import java.util.*; public class concurrentmodificationexception { public static void main(String[] args) { HashMap map = new HashMap(); map.put(1, 1); map.put(2, 2); map.put(3,3); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println('Map Value:' + map.get(key)); if (key.equals(2)) { map.put(1, 4); } } } }
산출:
Map Value:1 Map Value:2 Map Value:3
이 예제는 반복자가 지도를 반복하는 동안 지도의 크기가 변경되지 않으므로 완전히 잘 작동합니다. 지도만 업데이트됩니다. if 문 .
문자열 비교 C#
ConcurrentModificationException의 생성자
ConcurrentModificationException의 생성자에는 4가지 유형이 있습니다.
- 공개 ConcurrentModificationException() -
그러면 매개변수 없이 ConcurrentModificationException이 생성됩니다. - 공개 ConcurrentModificationException(문자열 메시지)
이는 예외를 지정하는 자세한 메시지와 함께 ConcurrentModificationException을 생성합니다. - 공개 ConcurrentModificationException(발생 가능한 원인)
이는 (cause==null?null:cause.toString())인 원인과 메시지를 사용하여 ConcurrentModificationException을 생성합니다. 원인은 나중에 Throwable.getCause()에 의해 검색됩니다. - 공개 ConcurrentModificationException(문자열 메시지, 발생 가능한 원인)
그러면 자세한 메시지와 원인이 포함된 ConcurrentModificationException이 생성됩니다. (cause==null?null:cause.toString()). 메시지는 나중에 Throwable.getMessage()에 의해 검색되고 원인은 나중에 Throwable.getCause()에 의해 검색됩니다.
다중 스레드 환경에서 ConcurrentModificationException을 방지하는 방법은 무엇입니까?
다중 스레드 환경에서 ConcurrentModificationException을 방지하려면 다음 방법을 따를 수 있습니다.
- 컬렉션 클래스를 반복하는 대신 배열을 반복할 수 있습니다. 이런 방식으로 우리는 작은 크기의 목록으로 매우 잘 작업할 수 있지만 배열 크기가 매우 크면 성능이 저하됩니다.
- 또 다른 방법은 목록을 동기화된 블록에 넣어 잠그는 것입니다. 이로 인해 멀티스레딩을 사용하는 유일한 목적이 포기되므로 이는 효과적인 접근 방식이 아닙니다.
- JDK 1.5 이상에서는 ConcurrentHashMap 및 CopyOnWriteArrayList 클래스를 제공합니다. 이 클래스는 동시 수정 예외를 방지하는 데 도움이 됩니다.
단일 스레드 환경에서 ConcurrentModificationException을 방지하는 방법은 무엇입니까?
반복자의 Remove() 함수를 사용하면 기본 컬렉션 개체에서 개체를 제거할 수 있습니다.