자바 개발 키트(Java Development Kit, JDK1.0) - 1996
Java1.1 - 1997
Java7 - 2011
Java10 - 2018.03
Java11 - 2018.09
역사의 흐름
- 자바 역사를 통틀어 가장 큰 변화는 자바 8에서 일어남
- 획기적이고 생산성에 변화
- 자바 10에서는 형 추론과 관련해서 약간의 변화
- 멀티코어 CPU 대중화와 같은 하드웨어적인 변화가 자바8에 영향을 미침
ex) 사과의 무게를 비교해서 목록에서 정렬하는 코드
자바8 이전 ver
Collection.sort(inventory, new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
)};
자바8 이후 ver
inventory.sort(comapring(Apple::getWeight));
-> 자바 8을 이용하면 자연어에 가깝게 간단한 방식으로 코드 구현 가능
Java8 등장 이전
- 랩톱이나 데스크톱에는 듀얼 혹은 쿼드 코어 이상을 지원하는 CPU 내장
- 자바 프로그램은 코어 중 하나만 사용(즉, 나머지 코어는 유후 idle 상태로 두거나, 운영체제나 바이러스 검사 프로그램과 프로세스 파워를 나눠서 사용)
- 자바 8 등장하기 이전에는 나머지 코어를 활용하려면 스레드를 사용하는 것이 좋다고 하였지만,,,,
- 스레드를 사용하면 관리하기 어렵고 많은 문제 발생
- 자바 1.0(스레드와 락, 메모리 모델 지원), 자바5(스레드 풀, 병렬 실행 컬렉션), 자바7(포크/조인 프레임워크)에서 다양한 해결책을 제공했지만, 여전히 개발자가 활용하기 쉽지 않았음
- 자바 8에서는 병령 실행을 새롭고 단순한 방식으로 접근할 수 있는 방법 제공
- 자바 9에서는 리팩티브 프로그래밍이라는 병렬 실행 기법을 지원, RxJava(리액티브 스트림 툴킷)
Java8
- 간결한 코드, 멀티코어 프로세서의 쉬운 활용이라는 2가지 요구사항을 기반
1. 스트림 API
- 데이터베이스 질의 언어에서 표현식을 처리하는 것처럼 병렬 연산을 지원하는 스트림이라는 새로운 API 제공
- 데이터베이스 질의 언어에서 고수준 언어로 원하는 동작을 표현하면, 구현(자바에서 스트림 라이브러리가 이 역할 수행)에서 최적의 저수준 실행 방법을 선택하는 방식으로 동작
- 병렬형 데이터를 표현하고 이들 데이터를 병렬로 처리할 수 있음을 유연하게 보여줌
- 스트림을 사용하면 에러를 자주 일으키며 멀티코어 CPU를 이용하는 방식보다 비용이 훨씬 비싼 키워드 synchronized를 사용하지 않아도 됨
- 스트림 API -> 메서드에 코드를 전달하는 간결기법(메서드 참조와 람다) + 인터페이스의 디폴트 메서드
2. 메서드에 코드를 전달하는 기법
3. 인터페이스의 디폴트 메서드
자바는 왜 변화할까?
- 프로그래밍 언어는 마치 생태계와 닮음
- 새로운 언어가 등장하면 진화하지 않은 기존 언어는 사장됨
ex) 에이다, 알골, 코볼, 파스칼, 델파이, 스노볼
- 시공을 초월하는 완벽한 언어는 없음, 장단점 존재
ex)
C, C++
장점 : 작은 런타임 풋프린트 덕분에 운영체제와 다양한 임베디드 시스템에서 인기
단점: 낮은 안정성 때문에 프로그램이 예기치 않게 종료됨, 바이러스 등이 침투할 수 있는 보안 구멍 존재 가능
Java, C#
장점 : 비교적 안전
단점 : C, C++에 비해 런타임 풋프린트 큼
- 빅데이터(테라바이트 이상의 데이터셋)라는 도전에 직면
-> 멀티코어 컴퓨터, 컴퓨팅 클러스터를 이용해서 빅데이터를 효과적으로 처리할 필요성 발생
대용량 데이터와 멀티코어 CPU를 효과적으로 활용해야 함
-> 병렬 프로세싱을 활용해야 하는 데, 이전의 자바로는 대응 불가능
- 자바 8은 더 다양한 프로그래밍 도구 그리고 다양한 프로그래밍 문제를 더 빠르고 정확하며 쉽게 유지보수할 수 있는 장점 제공
- 자바8에 추가된 기능은 자바에 없던 완전히 새로운 개념이지만 현재 시장에서 요구하는 기능을 효과적으로 제공
자바 8 설계의 밑바탕을 이루는 세 가지 프로그래밍 개념
1. 스트림 처리
- 스트림 : 한 번에 한 개씩 만들어지는 연속적인 데이터 항목들의 모임
- 이론적으로 프로그램은 입력 스트림에서 데이터를 한 개씩 읽어 들이며 마찬가지로 출력 스트림으로 데이터를 한 개씩 기록
- 어떤 프로그램의 출력 스트림은 다른 프로그램의 입력 스트림이 될 수 있음
ex) 파일의 단어를 소문자로 바꾼 다음에 사전순으로 단어를 정렬했을 때 가장 마지막에 위치한 세 단어를 출력하는 유닉스 프로그램
cat file1 file2 | tr "[A-Z]" "[a-z]" | sort | tail -3
- 유닉스의 cat 명령은 두 파일을 연결해서 스트림을 생성
- tr은 스트림의 문자를 번역
- sort는 스트림의 행을 정렬
- tail -3 스트림의 마지막 3개 행을 제공
- 유닉스 명령행에서는 파이프 "|" 를 이용해서 명령을 연결
- 유닉스에서는 여러 명령(cat, tr, sort, tail)을 병렬로 실행 -> cat이나 tr이 완료되지 않은 시점에서 sort가 행을 처리하기 시작할 수 있음
- 자바8에서는 java.util.stream 패키지에 스트림 API가 추가됨 -> Stream<T>
- 기존에는 한 번에 한 항목을 처리 -> 자바8에서는 우리가 하려는 작업을 (데이터베이스 질의처럼) 고수준으로 추상화해서 일련의 스트림으로 만들어 처리 가능
- 스트림 파이프라인을 이용해서 입력 부분을 여러 CPU 코어에 쉽게 할당할 수 있는 부가적 이득 존재
- 스레드라는 복잡한 작업을 사용하지 않으면서도 공짜로 병렬성을 얻을 수 있음
- 자바 8 스트림 API(4장 ~ 7장)
2. 동작 파라미터화로 메서드에 코드 전달하기
- 코드 일부를 API로 전달하는 기능
- 위 유닉스 예제에서 sort 명령에 파라미터 추가할 수도 있음, 역순 정렬 뿐만 아니라 다양한 정렬 우선순위가 존재 가능 -> 우선순위에 맞도록 sort 메서드에 명령을 내려야 함
- 자바8 이전의 자바에서는 메서드를 다른 메서드로 전달할 방법이 없었음
- Comparator 객체를 만들어서 sort에 넘겨주는 방법도 존재하지만, 너무 복잡하며 기존 동작을 단순하게 재활용한다는 측면에서 맞지 않음 (앞 부분 자바 비교 예제 코드 확인)
- 자바 8에서는 메서드를 다른 메서드의 인수로 넘겨주는 기능 제공 -> 동작 파라미터화

3. 병렬성과 공유 가변 데이터
- 병렬성을 얻는 대신 무엇을 포기해야 할까? -> 스트림 메서드로 전달하는 코드의 동작 방식을 조금 바꿔야 함
- 스트림 메서드로 전달하는 코드는 다른 코드와 동시에 실행하더라도 안전하게 실행되어야 함
- 보통 다른 코드와 동시에 실행하더라도 안전하게 실행할 수 있는 코드를 만들려면 공유된 가변 데이터에 접근하지 않아야 함
- 공유된 변수나 객체가 있으면 병렬성에 문제 발생 -> 두 프로세스가 공우된 변수를 동시에 바꾸려하면 어떻게 될까?
- 기존처럼 synchronized를 이용해서 공유된 가변 데이터를 보호하는 규칙을 만들 수 있음 (synchronized는 일반적으로 시스템 성능에 악영향 미침)
- 자바 8 스트림을 이용하면 기존의 자바 스레드 API보다 쉽게 병렬성을 활용 가능
- 다중 프로세싱 코어에서 syncrhonized를 사용하면 생각보다 훨씬 더 비싼 대가 필요(다중 처리 코어에서는 코드가 순차적으로 실행되어야 하므로 병렬이라는 목적을 무력화시킴)
자바가 진화해야하는 이유
- 자바는 계속 진화중
ex) 제네릭 등장, List가 List<String> 으로 변화
- 편리함 제공(컴파일을 할 때 더 많은 에러 검출 가능, 리스트의 유형을 알 수 있어 가독성 좋아짐)
- 틀에 박힌 Iterator 대신 for-each 루프 사용 가능
- 기존 값을 변화시키는 데 집중했던 고전적인 객체지향에서 벗어나 함수형 프로그래밍으로 다가섰다는 것이 자바 8의 가장 큰 변화
- 함수형 프로그래밍에서는 우리가 하려는 작업이 최우선시되며 그 작업을 어떻게 수행하는지(ex, 자료구조를 탐색하면서 컴포넌트 수정)는 별개의 문제로 취급
- 극단적으로 전통적인 객체지향 프로그래밍과 함수형 프로그래밍의 완전 상극
- 언어는 하드웨어나 프로그래머 기대의 변화에 부응하는 방향으로 변화해야함
- 자바 8에 추가된 새로운 기능 덕분에 기존에 다른 언어가 담당하던 생태계 영역을 자바 8이 정복하면서 프로그래머에게 더 많은 기회를 열고 있음