람다 캡처링 (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이다.