새소식

TIL

[TIL] 240509 <트러블 슈팅> ConcurrentModificationException

  • -

⚠️ 수강생을 삭제하는 메서드 실행 시 ConcurrentModificationException 발생하였음

 

    // 1-2) 수강생 삭제 (점수까지 삭제)
    public static void deleteStudent() {
        Scanner sc = new Scanner(System.in);
        System.out.print("삭제하고 싶은 수강생의 번호를 입력하세요 : ");
        int studentId = sc.nextInt();
        boolean flag=false;
        for (Student student : studentList) {
            if (student.getStudentID() == studentId) {
                flag=true;
                studentList.remove(student);
            }
        }
        if(flag){
            System.out.println("수강생 삭제가 완료되었습니다.\n");
        }
        else{
            System.out.println("목록에 없는 번호입니다. 다시 입력하세요.\n");
        }
    }

 

 

▶ 원인 : ArrayList를 향상된 for문을 이용하여 삭제

  • 향상된 for문을 이용한 ArrayList 순회는 내부에서 Iterator 이용
  • Iterator로 컬렉션을 순회하면서 수정하려고 할 시에 해당 예외 발생
  • 반복문에서 요소를 수정 후 (여기서는 remove 후) 다음 요소를 가져오기 위해 Iterator의 next() 메소드로 요소를 가져옴
  • 이때 next() 메소드 내부의 checkForComodification() 메소드로 컬렉션의 변경 여부를 확인하는데 여기서 예외 발생
    → remove를 하여 중간에 배열의 크기가 바뀌었기 때문

 

 

▶ 해결방법

  • 기본 for문 이용
    • 내부에서 Iterator를 이용하는 향상된 for문과는 다르게 인덱스를 이용하여 코드 내에서 직접 체크하기 때문에 오류 발생X
  • Collection.removeIf() 이용
  • 멀티 쓰레드 환경 : Map은 ConcurrentHashMap, ArrayList는 CopyOnWriteArrayList를 이용

 

 

▶ 기본 for문을 이용하여 해결

    // 1-2) 수강생 삭제 (점수까지 삭제)
    public static void deleteStudent() {
        Scanner sc = new Scanner(System.in);
        System.out.print("삭제하고 싶은 수강생의 번호를 입력하세요 : ");
        int studentId = sc.nextInt();
        boolean flag = false;
        for (int i = 0; i < studentList.size(); i++) {
            Student student = studentList.get(i);
            if (student.getStudentID() == studentId) {
                flag = true;
                studentList.remove(student);
            }
        }
        if (flag) {
            System.out.println("수강생 삭제가 완료되었습니다.\n");
        } else {
            System.out.println("목록에 없는 번호입니다. 다시 입력하세요.\n");
        }
    }

 

 

 

참고링크

 

[Java] ConcurrentModificationException

ConcurrentModificationException 해결 하기List에서 특정 조건에 해당하는 원소만 삭제 해야 할 경우가 있다.특정 숫자를 지워야 해야 한다면 아래와 같은 코드를 떠올릴 수 있을 것이다. 123456789List<Integer>

invicr.github.io

 

How to Avoid the Concurrent Modification Exception in Java

The ConcurrentModificationException in Java occurs when an object is attempted to be modified concurrently without permission.

rollbar.com

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.