람다 캡처링 (Lambda Capturing) 정리

2024. 5. 20. 23:05개발노트

람다 캡처링은 자바 람다 표현식이 자신이 정의된 범의 외부에 있는 변수를 사용할 수 있는 기능을 의미한다.

  • 캡처링 : 람다 표현식이 외부 변수를 사용하기 위해 이를 캡처하는 기능
  • final : 람다 표현식에서 사용되는 로컬 변수와 매개변수는 변경되지 않도록 제한해야 함
  • 일관성, 안정성, 스레드 안전성, 컴파일러 최적화
  • 사용 예 : 콜백 함수, 비동기 처리

 

왜 final 또는 사실상 final이어야 하는가?

로컬 변수와 메서드 매개변수는 final 또는 사실상 final이어야 람다 표현식 내부에서 사용할 수 있으며 이유는 아래와 같다.

  • 일관성 및 안정성: 람다 표현식은 비동기 코드나 콜백으로 사용되는데 이 때 람다 표현식 내부에서 사용하는 외부 변수가 변경될 수 있다면, 값이 예상치 못하게 변경될 위험이 있기 때문에
  • 스레드 안전성: 여러 스레드가 동시에 실행되는 환경에서는 변수가 변경될 수 있기 때문에 값의 일관성 유지를 위해
  • 컴파일러 최적화: 컴파일러는 해당 변수가 변경되지 않음을 보장할 수 있어야 최적화 하기 쉽다.

람다 캡처링의 사용 예시

버튼 클릭 이벤트에서 람다 캡처링

import javax.swing.JButton;
import javax.swing.JFrame;

public class LambdaCaptureExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Lambda Capture Example");
        JButton button = new JButton("Click Me");

        String message = "Button clicked!";

        button.addActionListener(e -> System.out.println(message));

        frame.add(button);
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

위 예제에서 message 변수는 람다 표현식 내부에서 사용되고 있다.

이 변수는 변경되지 않으므로 사실상 final이다.

 

비동기 처리에서 람다 캡처링

import java.util.concurrent.CompletableFuture;

public class AsyncLambdaCapture {
    public static void main(String[] args) {
        String taskName = "Async Task";

        CompletableFuture.runAsync(() -> {
            // 비동기 작업 수행
            System.out.println(taskName + " is running");
        });

        // 메인 스레드에서 다른 작업 수행
        System.out.println("Main thread is running");
    }
}

위 예제에서 taskName 변수는 비동기 작업을 수행하는 람다 표현식 내부에서 사용된다.

이 변수는 변경되지 않으므로 사실상 final이다.