📗 개발자 책 읽기/모던 자바 인 액션

[모던자바인액션] chapter 1. 자바 8 이후 추가된 것

민돌v 2022. 7. 29. 00:25

 

" Modern Java In Action - 모던 자바 인 액션, 전문가를 위한 자바 8, 9, 10 기법 가이드 "
독서 스터디 후, 책 내용을 정리한 글입니다.


1) Chapter 1. 자바 8, 9, 10, 11 : 무슨일이 일어나고 있는가?
2) Chapter 2. 동작 파라미터화 코드 전달하기
3) Chapter 3. 람다 표현식
4) Chapter 4. Stream
5) Chapter 5. Stream 활용
6) Chapter 6. Stream으로 데이터 수집하기 
7) Chapter 7. Stream 병렬 데이터처리와 성능

 

 

 


1. 자바가 멀티코어 병렬성을 더 쉽게 이용할 수 있도록 진화하는 과정

 

1) JAVA 8 - 자바 역사상 가장 큰 변화

자바는, 자바 8을 이용해 자연어에 더 가깝게 간단한 방식으로 코드를 구현하도록 변경되었다.

ex) 사과목록을 무게순으로 정렬하는 간단한 예시 코드

// java8 이전 
Collection.sort(inventory, new Comparator<Apple>() {
	public int compare(Apple a1, Apple a2) {
    	return a1.getWeight().compareTo(a2.getWeight);
	}
}


// java8 이후
inventory.sort (comparing(Apple::getWegiht));

 

CPU가 발전하여 멀티코어, 쿼드코어가 등장하였지만

자바 8 등장 이전에는, 멀티코어의 나머지의 코어를 활용하기 위해서는 스레드를 사용하는 것이 좋다고 누군가 조언했다고 이 책에서 말한다.

그러나, 스레드를 사용하면 관리하기 어렵고 많은 문제가 발생할 수 있다는 단점이 존재한다.


자바는 이러한 병렬 실행 환경을 쉽게 관리하고 에러가 덜 발생하는 방향으로 진화하려 노력했다.

➡️ 자바 8에서는 병렬 실행을 새롭고 단순한 방식으로 접근할 수 있는 방법을 제공하지만, 이 새로운 기법을 이용하기 위해서는 몆가지 규칙을 지켜야 하는데 이 책에서,  이 규칙에 대한 이야기한다고 한다. (화이팅)

 

자바 8은 간결한 코드, 멀티코어 프로세서의 쉬운 활용

이 2가지 요구사항을 기반의 목적성을 가진다고 한다.  이 2가지 목적성을 가지고 나온 자바 8의 변화를 요약하자면 다음과 같다.

  1. 스트림 API
  2. 메서드에 코드를 전달하는 기법
  3. 인터페이스의 디폴트 메서드

자바 8은 데이터베이스 질의 언어에서 표현식을 처리하는 것처럼, 

📌병렬 연산을 지원하는 스트림 이라는 새로운 API를 제공한다.

  • 데이터 베이스 질의 언어에서 고수준 언어(JAVA)로 원하는 동작을 표현하면
  • 구현에서 최적의 저수준 실행 방법을 선택하는 방식으로 동작한다. (자바에서는 스트림 라이브러리가 이 역할을 수행)
  • 즉, 스트림을 이용하면 에러를 자주 일으키며 멀티코어 CPU를 이용하는 것보다 비용이 훨씬 비싼 키워드 sychronized를 사용하지 않아도 된다.
  • 멀티코어 CPU의 각 코어는 별도의 캐시를 포함하고 있다, 락을 사용하면 이러한 캐시가 동기화되어야 하므로 속도가 느린 캐시 일관성 프로토콜 인터코어 통신이 이루어진다. (이게 무선소리...?)

 

 

조금 다른 관점에서 보자면

📌 스트림 API 덕분에, (2) 코드를 전달하는 간결 기법 (메서드 참조와 라다)(3) 인터페이스의 디폴트 메서드 존재할 수 있음을 알 수 있다.

 

➡️ 자바 8 은 함수형 프로그래밍 에서 위력을 발휘한다.

 

 


 

2. 자바 8의 변화

1) 자바가 지속적으로 변화하는 이유

  • 프로그래밍 언어는 마치 생태계와 닮았고, 새로운 언어가 등장하면 진화하지 않은 기존언어는 사장되어왔다.

 

자바의 시작

  • 자바는 처음부터 많은 유용한 라이브러리를 포함하는 잘 설계된 객체지향 언어로 시작했다.
  • 자바는 처음부터 스레드와 락을 이용한 소소한 동시성도 지원했다고 한다.
  • (자바의 하드웨어 중립적인 메모리 모델 때문에 멀티코어 프로세서에서 병렬적으로 수행되는 스레드는 싱글코어에서의 동작과 달리 예기치 못한 상황을 일으킬 수 있다.)

 

자바가 주요 프로그램 언어가 될 수 있었던 이유

  1. 코드를 JVM 바이트 코드로 컴파일하는 특징
  2. 모든 브라우저에서 가상 머신 코드를 지원하기 때문에 인터넷 애플릿 프로그램의 주요언어가 됨

 

📌 빅데이터의 등장 (병렬처리의 필요성)

  1. 하지만, 점점 빅데이터 시대가 오면서 병렬 프로세싱을 활용해야 하는 상황이 빈번해졌지만, 자바로는 충분히 대응할 수 없었다.
  2. 따라서, 자바 8에서는 이러한 병렬성이 강조되어서 나왔다. (자바가 변화하는 이유)

 

 

자바 8의 가장 큰 변화

  1. 스트림 API
  2. 동작 파라미터화로 메서드 전달 (메서드 매개변수 전달) 및 람다
  3. 병렬성과 공유 가변 데이터

 

 


3. 스트림 API

자바 8의 첫 번재 변화는 스트림 처리 이다, (Stream Processing)

 

스트림이란, 한 번에 한 개씩 만들어지는 연속적인 데이터 항목들의 모임이다.

  • 이론적으로 프로그램은 입력 스트림에서 데이터를 한개씩 읽어 들이며마찬가지로 출력 스트림으로 데이터를 한 개씩 기록한다.
  • 즉, 어떤 프로그램의 출력 스트림은 다른 프로그램의 입력 스트림이 될 수 있다.

 

📌 스트림  API 가 조립 라인처럼 어떤 항목을 연속으로 제공하는 어떤 기능이라고 단순하게 생각하자

  • 스트림 API는 파이프라인을 만드는 데 필요한 많은 메소드르 제공한다,

 

스트림 API의 핵심

  1. 자바에서 기존에는 한 번에한 항복을 처리했지만, 자바 8 에서는 (데이터베이스 질의처럼) 고수준으로 추상화해서 일련의 스트림으로 만들어 처리할 수 있다,
  2. 스트림 파이프라인을 이용해서 입력 부분을 여러 CPU 코어에 쉽게 할당할 수 있다는 부가적인 이득도 얻을 수 있다,
  3. 즉, 스레드라는 복잡한 작업을 사용하지 않으면서도 공짜로 병렬성을 읻을 수 있다,
    • (이 부분이 잘 이해가지 않지만,, 뒤를 좀 더 봐야겠다.) 

 

 

📌 내가 생각하는 스트림 API 정리 : 단순하게 일련의 파이프라인을 만들어, 파이프라인을 토대로 순차적인 반복작업을 가능하게 하는 것 같다는 느낌이 든다.


4. 동작 파라미터화로 메서드에 코드 전달

자바 8에 추가된 2번째 개념은, 코드 일부를 API로 전달하는 "동작 파라미터화"이다.

 

📌 동작 파라미터화란, 말 그대로 메서드를 다른 메서드의 인수로 넘겨주는 기능이다.

 

동작 파라미터를 사용하여 어떤 고정된 기능을 수행하는 메서드를 인자로 넘겨줌으로써, 스트림 API 파이프라인에 쉽게 적용할 수 있게된다.

 

이것이 가능한 이유는, 스트림 API는 연산으 ㅣ동작을 파라미터화할 수 있는 코드를 전달한다는 사상에 기초하기 때문이다.

 


 

5. 병렬성과 공유 가변 데이터

세 번째 프로그램밍 개념은 "병렬성을 공짜로 얻을 수 있다" 라는 말에서 시작된다.

 

👏 자바 8에서는, 병렬성을 얻는 대가로 스트림 메서드로 전달하는 코드의 동작 방식을 조금 바꿔야한다,

스트림 메서드로 전달하는 코드는 다른 코드와 동시에 실행하더라도 안전하게 실행될 수 있어야 한다.

 

📌 보통, 다른 코드와 동시에 실행해도 안전하게 실행하기 위해서는 공유된 가변데이터에 접근하지 않아야 한다.

이러한 함수를 순수함수, 부작용 없는 함수. 상태 없는 함수라 부른다.

 


 

6. 정리

  1. 언어 생태계의 모든 언어는 변화해서 살아남거나 그대로 머물면서 사라지게 된다. 지금은 자바의 위치가 견고하지만 코볼과 같은 언어의 선례를 떠올리면 자바가 영원히 지배적인 위치를 유지할 수 있는 것은 아닐 수 있다.
  2. 자바 8은 프로그램을 더 효과적이고 간결하게 구현할 수 있는 새로운 개념과 기능을 제공한다.
  3. 기존의 자바 프로그래밍 기법으로는, 멀티코어 프로세서를 온전히 활용하기 어렵다.
  4. 함수는 일급 값이다. 메서드를 어떻게 함수형값으로 넘겨주는, 익명 함수(람다)를 어떻게 구현하는지 기억하자
  5. 자바 8의 스트림 개념 중 일부는 컬렉션에서 가져온 것이다, 스트림과 컬렉션을 적절하게 활용하면 스ㅡ림의 인수를 병렬로 처리할 수 있으며 더 가독성이 좋은 코드를 구현할 수있다.
  6. 기존 자바 기능으로는 대규모 컴포넌트 기반 프로그래밍 그리고 진화하는 시스템의 인터페이스를 적절하게 대응하기 어려웠다, 디폴트 메서드를 이용해 기존 인터페이스를 구현하는 클래스를 바꾸지 않고도 인터페이스를 변경할 수 있다.
  7. 함수형 프로그래밍에서 NULL 처리 방법과 패턴 매칭 화룡 등 흥미로운 기법을 발견했다.