관리 메뉴

KorSA

[남궁성 '자바의 정석'] 156~163강 본문

Study Memos/Java

[남궁성 '자바의 정석'] 156~163강

Praiv. 2021. 11. 18. 17:52
320x100

※ 이 글은 남궁성 저자의 '자바의 정석' 156~163강을 수강한 후 정리한 내용입니다.

 

1. 임계영역 : 한 번에 한 개의 쓰레드만 접근 가능한 영역
    synchronized로 임계영역을 설정하는 방법 2가지

public synchronized void calcSum(){
	// Do Something
}

synchronized(참조변수){
	// Do Something
}


2. wait()과 notify()
    동기화의 효율을 높이기 위해 사용
    Object 클래스에 정의되어 있으며 동기화 블록 내에서만 사용 가능하다.
    wait(): 객체의 lock을 풀고 쓰레드를 해당 객체의 waiting pool에 넣는다
    notify(): waiting pool에서 대기중인 쓰레드 중의 하나를 깨운다.
    notifyAll(): waiting pool에서 대기중인 모든 쓰레드를 깨운다.

    Customer 쪽에서는 자원이 없을 때 wait()으로 lock을 반납하고,
    Provider 쪽에서는 자원이 추가되었을 때 notify()로 Customer에게 자원추가를 통지한다. 

3. ConcurrentModificationException 예외
    여러 데이터를 담고 있는 객체에서 읽기 수행 중 add(), remove()등의 변경이 발생할 경우 발생

4. wait(), notify()를 쓰면 대상이 불분명하다는 단점이 존재
    이를 해결하기 위해 나온게 Lock & Condition

5. Lock & Condition
    추후 추가 예정

 

6. 람다식(Lambda Expression)
    함수를 간단한 '식(Expression)'으로 표현하는 방법
    블록 안에 문장이 하나뿐일 때 괄호생략 가능하고 끝에 세미콜론(;) 붙이지 않는다
    람다식은 익명 함수가 아니라 익명 객체이다..!!
    익명 객체이기 때문에 함수형인터페이스 타입 변수로 다뤄야 한다.

MyFunctino2 f = (a, b) -> a > b ? a : b;


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

8. 함수형 인터페이스
    단 하나의 추상 메서드만 선언된 인터페이스
    @FunctionalInterface 어노테이션을 붙이면 컴파일러가 문법 체크해줌. 쓰면 좋음.
    추상 메서드를 선언할 때 'public abstract'는 생략 가능하다. 

    인터페이스 함수의 기본이 'public abstract' 니까.

9. 함수형인터페이스 타입의 매개변수는 람다식을 전달하면 된다는 뜻이다.

// 선언
void aMethod(MyFunction f){
	f.myMethod();
}

// 호출
aMethod(()-> System.out.println("myMethod()"));


10. 함수형인터페이스 타입을 리턴타입으로 쓸 수도 있다.

MyFunction myMethod(){
	return ()->{};
}

 

11. java.util.function 패키지
    자주 사용되는 다양한 함수형 인터페이스를 제공
    Runnable : 매개변수도 없고, 반환값도 없음

void run();


    Supplier<T> : 매개변수는 없고, 반환값은 있음

T get();


    Consumer<T> : Supplier와 반대로 매개변수만 있고, 반환값이 없음

void accpet(T t);


    Function<T, R> : 일반적인 함수, 하나의 매개변수를 받아서 결과를 반환

R apply(T t);


    Predicate<T> : 매개변수는 하나이고 조건식을 표현하는데 사용됨

boolean test(T t);


    BiConsumer<T, U> : 두 개의 매개변수만 있고 반환값이 없음

void accept(T t, U u);


    BiPredicate<T, U> : 조건식을 표현하는 데 사용됨. 매개변수는 둘, 반환값은 boolean

boolean test(T t, U u);


    BiFunction<T, U, R> : 두 개의 매개변수를 받아서 한개의 결과를 반환

R apply(T t, U u);


    UnaryOperator<T> : Function의 자손. Function과 달리 매개변수와 결과의 타입이 같다

T apply(T t);


    BinaryOpeartor<T> : BiFunction의 자손. BiFunction과 달리 매개변수와 결과의 타입이 같다

T apply(T t, T t);


    JAVA에서 이렇게 만들어둔 이유는 왠만하면 매개변수 1개, 2개일 땐 만들어둔거 쓰라는 의미

12. 메서드 참조(method reference)
    하나의 메서드만 호출하는 람다식은 '메서드 참조'로 간단히 할 수 있다.

Function<String, Integer> f = (String s) -> Integer.parseInt(s);
Function<String, Integer> f = Integer::parseInt; // 메서드 참조, 위 코드와 동일한 의미


13. 생성자의 메서드 참조

Function<Integer, MyClass> s = (i) -> new MyClass(i);
Function<Integer, MyClass> s = MyClass::new; // 메서드 참조, 위 코드와 동일한 의미

 

14. 스트림
    다양한 데이터 소스(컬렉션, 배열)를 표준화된 방법으로 다루기 위한 것
    Collections Framework의 사용방법이 드디어 통일됨
    JDK 1.8에 나옴

15. Collection을 Stream으로 변환할 수 있음

Stream<Integer> intStream = list.stream();


16. 스트림 사용법
    1) 스트림 만들기
    2) 중간 연산을 n번 수행하기
    3) 최종 연산 1번해서 결과 얻기


17. 스트림의 특징
    1) 스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다.
    2) 스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)
    3) 스트림은 최종 연산 전까지 중간연산이 수행되지 않는다. (지연된 연산)

        지연된 연산이기 때문에 무한 스트림도 사용할 수 있다.

IntStream intStream = new Random().ints(1,46); // 무한 스트림.. 랜덤값을 무한히 내보낸다.
intStream.distinct().limit(6).sorted() // 중간연산
	.forEach(i->System.out.print(i+",")); // 최종연산


    4) 스트림은 작업을 병렬로 처리할 수 있다. (병렬 스트림)
        함수형 프로그래밍은 빅데이터 분야에서 큰 작업들을 빨리 처리할 수 있어서 인기가 있다.

int sum = strStream.parallel()
		.mapToInt(s -> s.length()).sum(); // 모든 문자열의 길이의 합


    5) 기본형 스트림을 제공한다.
       IntStream, LongStream, DoubleStream
       오토박싱&언박싱의 비효율이 제거됨 (Stream<Integer> 대신 IntStream 사용)
       숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공

 

728x90
728x90
Comments