CompletableFuture 클래스 CompletableFuture 클래스는 java8에 도입된 Future, CompletionStage 인터페이스의 구현체다. public class CompletableFuture implements Future, CompletionStage { ... } Future 비동기적인 작업을 수행 해당 작업이 완료되면 결과를 반환하는 인터페이스 java5부터 java.util.concurrency package에서 비동기의 결과값을 받는 용도로 사용 CompletionStage 비동기적인 작업을 수행 해당 작업이 완료되면 결과를 처리하거나 다른 CompletionStage를 연결 하는 인터페이스 쉽게 말하자면, 하나의 비동기 작업을 수행하고 완료가 되었을 때, 여기에 ..
익명클래스 vs 람다 익명클래스 public class AnonymousClass { public static void main(String[] args) { IntBinaryOperator plus = new IntBinaryOperator() { @Override public int applyAsInt(int left, int right) { return left + right; } }; } } ▷ 바이트코드 public class com/whiteship/white_ship_study/week15/AnonymousClass { static INNERCLASS com/whiteship/white_ship_study/week15/AnonymousClass$1 null null public static ..
수강완료한 강의 복습해보자 (코딩으로 학습하는 GoF의 디자인 패턴) 플라이웨이트 패턴(Flyweight Pattern) 객체를 가볍게 만들어 메모리 사용을 줄이는 패턴. 자주 변하는 속성(또는 외적인 속성, extrinsit)과 변하지 않는 속성(또는 내적인 속성, intrinsit)을 분리하고 재사용하여 메모리 사용을 줄일 수 있다. 적용 전 코드 (Before) Character.java public class Character { private char value; private String color; private String fontFamily; private int fontSize; public Character(char value, String color, String fontFamily..
wait(), notify(), notifyAll() synchronized로 동기화해서 공유 데이터를 보호할때 특정 스레드가 객체의 락을 가진 상태로 오랜 시간을 보내지 않도록 하는것도 중요하다. 락을 오랜시간 보유하게되면, 다른 스레드들은 모두 해당 객체의 락을 기다리느라 다른 작업들도 원할히 진행되지 않는다. 이러한 상황을 위해 고안된 것이 wait), notify()다. wait() 동기화된 임계 영역의 코드를 수행하다가 더이상 작업을 진행할 상황이 아니라면, 일단 wait()을 호출하여 스레드가 락을 반납하고 기다리게한다. 그러면 다른 스레드가 락을 얻어 해당 객체에 대한 작업을 수행할 수 있게된다. notify() 나중에 작업을 진행할 수 있는 상황이 되면 notify()를 호출해서, 작업을 ..
ThreadLocal ThreadLocal 클래스에는 get, set 메서드가 있는데 이를 호출하는 스레드마다 다른 값을 사용할 수 있도록 관리해준다. ThreadLocal 클래스의 get 메서드를 호출하면 현재 실행중인 스레드에서 최근에 set 메서드를 호출해 저장했던 값을 가져올 수 있다. 스레드 로컬 변수는 변경 가능한 싱글턴이나 전역 변수 등을 기반으로 설계되어있는 구조에서 변수가 임의로 공유되는 상황을 막기위해 사용하는 경우가 많다. 쉽게말해서, ThreadLocal이란 스레드 단위로 로컬 변수를 제공하는 클래스다. ThreadLocal 동작방식 ThreadLocalMap 스레드가 코드를 실행하면서 만나게되는 모든 ThreadLocal 변수를 threadLocals 객체에 저장한다. Thread..
volatile 변수 volatile로 선언된 변수의 값을 바꿨을때 다른 스레드에서 항상 최신 값을 읽어갈 수 있도록 해준다. ▶ 변수의 값을 읽을때 CPU cache에 저장된 값이 아닌 Main 메모리에서 읽는다. 기존에는 CPU Cache에만 반영되고, 실제 Main Memory에는 반영되지 않는다. Volatile은 Main Memory에 즉시 저장한다. 특정 변수를 선언할때 volatile 키워드를 지정하면, 컴파일러와 런타임 모두 '이 변수는 공유해 사용하고, 따라서 실행 순서를 재배치 해서는 안된다.' 라고 이해한다. volatile 변수는 프로세서의 레지스터에 캐시되지도 않고, 프로세서 외부의 캐시에도 들어가지 않기 때문에 항상 다른 스레드가 보관해둔 최신의 값을 읽어갈 수 있다. ▶ 그러므..
예제 Counter.java package org.example.atomic; public class Counter { private int c = 0; public void increment() { c++; } public void decrement() { c--; } public int value() { return c; } } 위 예제는 멀티 스레드에서 접근하는 요청에 대한 정합성 확보가 어렵다는 문제점이 있다. 이를 해결하기 위해 각 메서드에 synchronized 키워드를 붙여 객체에 록을 걸어보자. SynchronizedCounter.java package org.example.atomic; public class SynchronizedCounter { private int c = 0; pub..
분할 반복 Spliterator 자바 8에서 Split과 Iterator의 합성어로 Spliterator 인터페이스를 제공한다. Iterator 예제 HelloPerson.java package org.example.Spliterator; import java.util.ArrayList; import java.util.List; public class HelloPerson { private String firstName; private String lastName; private String country; public HelloPerson(String firstName, String lastName, String country) { this.firstName = firstName; this.lastNa..
스트림의 병렬 처리 스트림 API에서는 parallelStream 메서드를 이용해서 스트림 객체를 생성하는 것만으로도 병렬 처리가 된다. 손쉽게 대량의 데이터를 병렬 처리하는 코드를 작성할 수 있다. ParallelReduceMinMax.java package org.example.streamparallel; import java.util.Arrays; import java.util.List; public class ParallelReduceMinMax { public static void main(String[] args) { List intList = Arrays.asList(4, 2, 8, 1, 9, 6, 7, 3, 5); // 최대 값 구하기 - 병렬 int max = intList.paralle..
Future 포크/조인 프레임워크에서 살펴본 RecursiveTask와 RecursiveAction의 명세서를 살펴보면 두 클래스 모두 Future 인터페이스를 구현한 추상 클래스이며 Future 인터페이스는 자바 5에서 공개한 컨커런트 API에 포함되어있다. Future 인터페이스는 비동기 연산의 결과를 표현한다. 해당 인터페이스에서 제공하는 메서드 목록을 보면 연산 작업이 완료되었는지 확인하고, 완료될 때까지 대기하고, 모든 연산이 완료된 후의 결과를 조회하는 기능을 제공한다. 제공 메서드 메서드 설명 cancel() 현재 task의 중단을 시도한다. isDone(), isCancelled() 비동기 연산이 종료 혹은 취소되었는지 확인한다. get() 결괏값을 응답받을 때까지 대기한다. 예제코드 Fu..
포크/조인 프레임워크 컨커런트 API를 최종적으로 완성한 것은 자바 7에서 제공한 포크/조인 프레임워크다. 포크/조인 프레임워크는 java.util.concurrent 패키지의 핵심인 ExecutorService 인터페이스를 구현한 클래스다. 새로운 기능이 아니라, 인터페이스의 구현체가 추가된 것으로 이해하면 된다. 이 프레임워크의 주된 목적은 멀티 프로세서 혹은 멀티 코어를 가지고 있는 하드웨어 자원을 최대한 효율적으로 활용해서 병렬 처리가 가능하도록 하는 것이다. - 포크 (Fork) : 다른 프로세스 혹은 스레드(태스크)를 여러 개로 쪼개서 새롭게 생성한다는 의미이다. - 조인 (Join) : 포크해서 실행한 프로세스 혹은 스레드(태스크)의 결과를 취합한다는 의미이다. 어떤 할일이 있을때 그 일을 ..
Executors 클래스 - Executor 인터페이스 : 컨커런트 API의 핵심 인터페이스다. 이 인터페이스를 구현한 여러 종류의 클래스를 기본으로 제공한다. - 스레드 풀 : 스레드를 관리하기 위한 풀이다. 병렬 프로그래밍에서 스레드를 관리하기 위한 기능을 제공한다. - 포크/조인 프레임워크 : JDK7에서 새롭게 선보인 포크/조인 프레임워크를 이용하면 스레드 간의 대기와 연관 관계 등을 정의할 수 있다. java.util.concurrent 패키지에서 제공하는 Executor 인터페이스 인터페이스 설명 Executor 새로운 태스크를 생성하는데 가장 기본이 되는 인터페이스다. ExecutorService Executor 인터페이스의 하위 인터페이스다. Executor 인터페이스에서 제공하는 기능 외..