전체 글(100)
-
[Java] volatile 키워드
Java에서는 가시성 문제를 해결하기 위해 volatile 키워드를 사용하게 된다. 이번 글에서는 volatile 키워드를 통해 가시성을 보장하는 방법을 간단한 예시와 함께 알아보자. 가시성을 보장하지 못한 예제 public class Volatile { private static boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(() -> { int i = 0; while (!stopRequested) { i++; } }); backgroundThread.start(); Thread.sleep(1000); stopReques..
2022.08.25 -
[Java] Java의 동시성 이슈
동시성 프로그래밍에서 발생할 수 있는 문제점 컴퓨터의 CPU와 RAM의 관계도를 그려보면 다음과 같은 그림이 될 것이다. CPU가 어떤 작업을 처리하기 위해 데이터가 필요할 때, CPU는 RAM의 일부분을 고속의 저장 장치인 CPU Cache Memory로 읽어들인다. 이 읽어들인 데이터로 명령을 수행하고, RAM에 저장하기 위해서는 데이터를 CPU Cache Memory에 쓴 다음 RAM에 쓰기 작업을 수행한다. 그러나 CPU가 캐시에 쓰기 작업을 수행했다고 해서 바로 RAM으로 쓰기 작업을 수행하지 않는다. 반대로 읽기 작업도 해당 데이터가 RAM에서 변경이 되었다고 해도, 언제 CPU Cache Memory가 아닌 RAM에서 데이터를 읽어 들여서 CPU Cache Memory를 업데이트 할지 보장하..
2022.08.25 -
[일문일답][Java] Fail Fast, Fail Safe Iterator
Fail Fast , Fail Safe ? 자바에선 컬렉션 프레임워크의 하나인 Iterators(반복자)가 존재한다. 자바 컬렉션은 2가지타입의 Iterators를 지원하는데 그것이 Fail Fast, Fail Safe이다. 이러한 Iterators들은 예외처리에서 배우 유용하다. Fail Fast Iterator는 가능한 한 빨리 실패를 노출하고 전체 작업을 중지하여 작업을 중단한다. 반면, Fail Safe Iterator는 장애가 발생할 시 작업을 중단하지 않는다. 대신 가능한 한 실패를 피하려고 한다. Fail Fast iterator @Test void iteratorTest() { Map addName = new HashMap(); addName.put("Lee", "Football"); ad..
2022.08.25 -
[일문일답][Java] Iterator 인터페이스와 Iterable 인터페이스
Iterator 인터페이스 public interface Iterator { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer
2022.08.25 -
[Java] Stream API의 고급 활용 및 사용 시 주의점 - 4/5
1. FlatMap을 통한 중첩 구조 제거 [ FlatMap이란? ] 만약 우리가 처리해야 하는 데이터가 2중 배열 또는 2중 리스트로 되어 있고, 이를 1차원으로 처리해야 한다면 어떻게 해야 할까? 이러한 경우에 map을 이용해도 결과는 2중 Stream의 형태일 것이다. 이처럼 중첩 구조를 한 단계 제거하기 위한 중간 연산이 필요한데, 이것이 바로 flatMap이다. flatMap은 Function 함수형 인터페이스를 매개 변수로 받고 있다. 예를 들어 다음과 같이 2중 리스트가 존재한다고 할 때, 이를 1중 리스트로 변환하기 위해서 flatMap을 이용할 수 있다. // flatMap 함수 Stream flatMap(Function
2022.08.25 -
[Java] Stream API의 활용 및 사용법 - 3/5
1. Stream 생성하기 앞서 설명한대로 Stream API를 사용하기 위해서는 먼저 Stream을 생성해주어야 한다. 타입에 따라 Stream을 생성하는 방법이 다른데, 여기서는 Collection과 Array에 대해서 Stream을 생성하는 방법에 대해 알아보도록 하자. [ Collection의 Stream 생성 ] Collection 인터페이스에는 stream()이 정의되어 있기 때문에, Collection 인터페이스를 구현한 객체들(List, Set 등)은 모두 이 메소드를 이용해 Stream을 생성할 수 있다. stream()을 사용하면 해당 Collection의 객체를 소스로 하는 Stream을 반환한다. // List로부터 스트림을 생성 List list = Arrays.asList("a"..
2022.08.25