본문 바로가기
안드로이드

[Android] ConcurrentModificationException 에러 해결

by 코딩히어로 2022. 10. 28.
728x90

1


Java를 이용해서 안드로이드 프로그래밍 도중에 ArrayList를 사용하는 부분에서

ConcurrentModificationException 에러가 발생했습니다

해당 에러는 일반적인 상황에서는 발생하지 않았고 향상된 for문을 사용하는 과정에서

발생했는데 에러가 발생한 코드는 다음과 같습니다

if(master_client.size()!=0) {
    int check_count = 0;
    for (PersonClient p : master_client) {
        if (p.GetId().equals(slave_client.get(0).GetId())) {
            Log.i("디버깅", "마스터 제거 = " + master_client.get(check_count).GetId());
            master_client.remove(check_count);
        }
        check_count++;
    }
}

위 코드에서 문제가 되는 부분은 master_client.remove라는 부분입니다

master_client라는 ArrayList를 제거하는 과정인데 왜 이부분인 문제인지 찾아보니

ArrayList에서 해당 에러가 발생하는 이유는 동시성에서 발생이 됩니다

 

동시성이란 무엇이냐하면 자바 프로그램 자체가 객체지향이다 보니

ArrayList를 향상된 for문으로 조회하는 도중에 remove 처리가 되기 때문에 문제가 발생합니다

 

즉 위의 구문은 master_client ArrayList의 Data형인 PersonClient 객체를 치환해야 하지만

master_client가 size가 1일경우 remove 해버리면 다음 for문에서는 당연히 참조객체가 없기 때문에

문제가 발생하는데 이것을 해결하려면 간단하게 break문을 걸어주면 됩니다

즉 remove하는 순간 for문을 빠져나가면 다음참조를 하지 않기때문에 문제가 해결되는것이죠

if(master_client.size()!=0) {
    int check_count = 0;
    for (PersonClient p : master_client) {
        if (p.GetId().equals(slave_client.get(0).GetId())) {
            Log.i("디버깅", "마스터 제거 = " + master_client.get(check_count).GetId());
            master_client.remove(check_count);
            break;
        }
        check_count++;
    }
}

하지만 해당 방법은 list를 순회하다가 한개의 element만 제거하는 경우에는 문제가 없지만

전체 size를 순회해야 하는 경우에는 다른 문제가 될 수 있습니다

 

이럴경우에는 CopyOnWriteArrayList를 이용하면 문제없이 해결이 가능합니다

master_client = CopyOnWriteArrayList<PersonClient>();

if(master_client.size()!=0) {
    int check_count = 0;
    for (PersonClient p : master_client) {
        if (p.GetId().equals(slave_client.get(0).GetId())) {
            Log.i("디버깅", "마스터 제거 = " + master_client.get(check_count).GetId());
            master_client.remove(check_count);
        }
        check_count++;
    }
}

 

728x90
반응형

댓글