728x90

join()

지정된 시간 동안 특정 스레드가 작업하는 것을 기다린다.

예외처리를 해야 된다.(InterruptedException이 발생하면 작업 재개)

 

yield()

남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 스레드)은 실행 대기한다.

yield()와 interrupt()를 적절히 사용하면, 응답성과 효율을 높일 수 있다.

 

스레드의 동기화

멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.

진행 중인 작업이 다른 스레드에게 간섭받지 않게 하려면 동기화가 필요

동기화하려면 간섭받지 않아야 하는 문장들을 임계 영역으로 설정

임계 영역은 락을 얻은 단 하나의 스레드만 출입가능(객체 1개에 락 1개)

 

synchronized를 이용한 동기화

synchronized로 임계 영역(lock이 걸리는 영역)을 설정하는 방법 2가지

1. 메서드 전체를 임계 영역으로 지정
public sychronized void calcsum() {
   // ...             임계 영역
}
2. 특정한 영역을 임계 영역으로 지정
sychronized(객체의 참조변수) {
   // ...             임계 영역
}

wait()과 notify()

동기화 효율을 높이기 위해 wait(), notify()를 사용

Object클래스에 정의되어 있으며, 동기화 블록 내에서만 사용할 수 있다.

  • wait() - 객체의 lock을 풀고 스레드를 해당 객체의 waiting pool에 넣는다.
  • notify() - waiting pool에서 대기 중인 쓰레드 중의 하나를 깨운다.
  • notifyAll() - waiting pool에서 대기중인 모든 스레드를 깨운다.

람다식

함수(메서드)를 간단한 식으로 표현하는 방법

익명 함수(이름이 없는 함수, anonymous function)

함수와 메서드의 차이

  • 근본적으로 동일. 함수는 일반적 용어, 메서드는 객체지향 개념 용어
  • 함수는 클래스에 독립적, 메서드는 클래스에 종속적

람다식 작성하기

  1. 메서드의 이름과 반환 타입을 제거하고 '->'를 블록{ } 앞에 추가한다.
  2. 반환 값이 있는 경우, 식이나 값만 적고 return문 생략 가능(끝에 ; 안 붙임)
  3. 매개변수의 타입이 추론 가능하면 생략 가능(대부분의 경우 생략 가능)

람다식 작성하기 - 주의 사항

  1. 매개변수가 하나인 경우, 괄호() 생략 가능(타입이 없을 때만)
  2. 블록 안의 문장이 하나뿐 일 때, 괄호 { } 생략 가능(끝에 ; 안 붙임)
  3. 단 하나뿐인 문장이 return문이면 괄호 { } 생략 불가

람다식은 익명 함수가 아니라 익명 객체이다.

 

함수형 인터페이스

함수형 인터페이스 - 단 하나의 추상 메서드만 선언된 인터페이스

함수형 인터페이스 타입의 참조 변수로 람다식을 참조할 수 있음(단, 함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환 타입이 일치해야 함)

 

생성자와 메서드 참조

콜론 두 개 (:: – 이중 콜론 연산자)의 정식 명칭은 메서드 참조 표현식(method reference expression)이며, 결론부터 말하자면 람다식에서 파라미터를 중복해서 쓰기 싫을 때 사용합니다.

람다 표현식(expression)에서만 사용 가능하고, 사용 방법은 [인스턴스]::[메서드명(또는 new)]

Supplier<MyClass> s = () -> new MyClass();
Supplier<Myclass> s = MyClass::new;

 

스트림

다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream(); // 컬렉션
Stream<String> strStream = Stream.of(new String[] {"a", "b", "c"}); // 배열
Stream<Integer> evenStream = Stream.iterate(0, n -> n + 2); // 0, 2, 4, 6, ...
Stream<Double> randomStream = Stream.generate(Math::random); // 람다식
IntStream intStream = new Random().ints(5); // 난수 스트림(크기가 5)

스트림

스트림이 제공하는 기능 - 중간 연산과 최종 연산

  • 중간 연산 - 연산 결과가 스트림인 연산. 반복적으로 적용 가능
  • 최종 연산 - 연산 결과가 스트림이 아닌 연산. 단 한 번만 적용 가능(스트림의 요소를 소모)

Stream.distinct(). limit(5). sorted(). forEach(System.out::println)

. distinct() : 중간 연산,. limit(5) : 중간 연산,. sorted() : 중간 연산,. forEach(System.out::println) : 최종 연산

스트림은 데이터 소스로부터 데이터를 읽기만 할 뿐 변경하지 않는다.

스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)

최종 연산 전까지 중간 연산이 수행되지 않는다. - 지연된 연산

 

 

728x90

+ Recent posts