Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바(Java)에서 ArrayList를 동기화하는 2가지 방법 총정리

ArrayListAbstractList 클래스의 하위 클래스로, 크기가 가변적인 요소 컬렉션을 저장하는 데 사용됩니다. 새로운 요소가 추가되면 내부 배열의 크기가 늘어나고, 요소가 제거되면 크기가 줄어들기 때문에 크기 조절이 가능한 배열(resizable array) 또는 동적 배열(dynamic array)이라고 부릅니다. 또한 ArrayList는 중복 값과 null 값을 허용한다는 특징이 있습니다.

다만 ArrayList는 기본적으로 스레드에 안전하지 않기 때문에, 멀티스레드 환경에서 사용하려면 별도의 동기화 처리가 필요합니다. 자바에서 ArrayList를 동기화하는 대표적인 방법은 다음의 두 가지입니다.

1. Collections.synchronizedList() 메서드

synchronizedList() 메서드는 자바에서 컬렉션을 스레드 안전하게 만들 때 사용하는 유틸리티 메서드입니다. 일반 ArrayList를 감싸서 동기화된 리스트로 변환해 줍니다.

문법

public static List<T> synchronizedList(List<T> list)

예제

import java.util.*;
public class SynchronizedListTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("IND");
        list.add("AUS");
        list.add("WI");
        list.add("NZ");
        list.add("ENG");
        List<String> synlist = Collections.synchronizedList(list);
        synchronized(synlist) {
            Iterator<String> itr = synlist.iterator();
            while(itr.hasNext()) {
                String str = itr.next();
                System.out.println(str);
            }
        }
    }
}

실행 결과

IND
AUS
WI
NZ
ENG

참고: synchronizedList()로 생성한 리스트도 반복(iteration) 중에는 수동으로 동기화 블록을 사용해야 합니다. 위 예제에서 synchronized(synlist) 블록을 사용한 이유가 바로 이것이며, 이를 생략하면 순회 도중 ConcurrentModificationException이 발생할 수 있습니다.

2. CopyOnWriteArrayList

CopyOnWriteArrayList는 지정된 컬렉션의 순서대로 요소 목록을 생성하는 클래스로, 스레드 안전(thread-safe)한 동시 접근을 지원하는 ArrayList입니다. 리스트가 수정될 때마다 내부 배열의 새로운 복사본(copy)을 생성하는 방식으로 동작하기 때문에, 읽기 작업이 많고 쓰기 작업이 적은 환경에서 특히 효과적입니다.

문법

public class CopyOnWriteArrayList<E> extends Object implements List<E>, RandomAccess, Cloneable, Serializable

예제

import java.util.*;
import java.util.concurrent.*;
public class CopyOnWriteArrayListTest {
    public static void main(String[] args) {
        CopyOnWriteArrayList list = new CopyOnWriteArrayList();
        list.add("Java");
        list.add("Scala");
        list.add("Python");
        list.add("Selenium");
        list.add("ServiceNow");
        System.out.println("동기화된 ArrayList 출력: ");
        Iterator itr = list.iterator();
        while(itr.hasNext()) {
            String str = itr.next();
            System.out.println(str);
        }
    }
}

실행 결과

동기화된 ArrayList 출력:
Java
Scala
Python
Selenium
ServiceNow

참고: CopyOnWriteArrayList는 반복자(iterator)를 생성하는 시점의 배열 스냅샷을 기반으로 순회하기 때문에, 별도의 동기화 블록 없이도 안전하게 반복 작업을 수행할 수 있습니다.