나누고 싶은 개발 이야기

Data Engineer로서 기록하고 공유하고 싶은 기술들. 책과 함께 이야기합니다.

Language/Java

AtomicIntegerFieldUpdater

devidea 2023. 4. 8. 00:33

멀티 스레드 환경에서 원자성을 보장하는 Integer 변수가 필요하다면 대체로 AtomicInteger를 많이 사용한다. 그런데 AtomicInteger를 클래스 내부 변수에 추가해 사용하면 클래스 객체를 만들 때 마다 내부에 AtomicInteger 객체도 만들어지므로 이중으로 객체가 생성된다고 볼 수 있다. 예를 들면 아래와 같다.

public class BaseClass {
	private final AtomicInteger counter = new AtomicInteger();

	public add() {
		counter.getAndIncrement();
	}
}

AtomicInteger는 getAndIncrement, getAndDecrement 같은 함수를 제공하며, 멀티 스레드 어플리케이션에서 카운터 등으로 많이 사용된다. 그런데 앞서 설명했듯이 AtomicInteger를 변수로 포함하는 객체를 생성하면 객체를 이중으로 생성하는 단점이 있다. 그래서 AtomicInteger와 같이 원자적인 변환을 하지만 이중으로 객체가 생성되는 단점을 보완하는 방법이 있다.

 

AtomicIntegerFieldUpdater 클래스[각주:1]를 사용하면 된다. 사용하는 예제 코드를 먼저 살펴보자. 예제코드는 다음 블로그[각주:2]에서 가져왔다.

public class AtomicFieldUpdaterExample {
    private static class Test {
        volatile int count;

        public int getCount() {
            return count;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerFieldUpdater<Test> countFieldUpdater =
                AtomicIntegerFieldUpdater.newUpdater(Test.class, "count");
        Test test = new Test();

        ExecutorService es = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            es.execute(() -> {
                for (int c = 0; c < 100; c++) {
                    countFieldUpdater.incrementAndGet(test);
                }
            });
        }
        es.shutdown();
        es.awaitTermination(10, TimeUnit.MINUTES);
        System.out.println("count: " + test.getCount());
    }
}

AtomicIntegerFieldUpdater는 volatile로 선언된 int 변수를 원자적으로 수정할 수 있다. 값의 증가를 AtomicIntegerFieldUpdater의 incrementAndGet 함수를 사용했다. volatile int로 변수를 선언했기에 클래스 객체를 생성하더라도 중복으로 내부 객체가 생성되는 낭비를 줄일 수 있다. 위 코드를 실행해 보면 int 변수가 원자성을 유지하고 있음을 알 수 있다.

 

netty 창시자 이희승님의 유튜브에서 AtomicIntegerFieldUpdater를 실제로 사용하여 설명과 함께 라이브 코딩[각주:3]하시는 부분을 첨부하니 참조하면 좋다.

 

 

 
 
반응형

'Language > Java' 카테고리의 다른 글

[NIO] WatchService  (0) 2020.07.28
[multi thread] CountDownLatch  (0) 2020.06.04
[multi thread] Semaphore  (0) 2020.06.02
[Java9] Collections, Streams  (0) 2020.03.13
Proxy를 통한 Restful API 호출 by Java  (0) 2019.12.09