Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- BEAN
- 싱글톤
- Setter
- vue-cli
- thymeleaf
- Spring
- Security
- Java
- HTTP
- JPA
- 프로토타입
- Singleton
- Excel
- HTTP 메서드
- 라이프 사이클
- DB
- Repository
- cache
- dependency injection
- vuex
- Stateless
- di
- Vue.js
- VUE
- 의존성 주입
- 캐시
- Kotlin
- js
- 로그인
- javascript
Archives
- Today
- Total
jhhan의 블로그
Java의 정석을 시작하자(4)(2/7) 본문
13장 이후부터는 여기다 작성하는 것으로 결정했다.
13장. 쓰레드
-프로세스 & 쓰레드
- 프로세스 : 실행 중인 프로그램
- 프로세스 구성 : 필요한 데이터 & 메모리 등의 자원, 쓰레드
- 쓰레드 : 실제로 작업을 수행하는 것
- 쓰레드가 둘 이상이면 멀티쓰레드 프로세스라고 한다.
- ex) 프로세스 = 공장 , 쓰레드 = 일꾼 이라고 생각하면 이해하기 쉽다.
-멀티쓰레딩
장점 | 단점 |
- CPU사용률을 향상시킨다. |
- 자원을 공유하는 특성 존재 - 동기화(synchronization), 교착상태(deadlock) 같은 문제들을 고려하면서 프로그래밍 진행 |
-쓰레드의 구현 & 실행
- Thread클래스를 상속받는다.
- Runnable인터페이스를 구현한다.
- 2가지 방법 모두 상관없지만 Thread클래스를 상속받으면 다른 클래스 상속이 안되기 때문에 보통은 Runnable인터페이스 구현을 한다.
- Runnable인터페이스는 run()만 정의되어 있는 간단한 인터페이스이다.
** 쓰레드의 구현 & 실행에 대한 예제이다.
** Thread클래스와 Runnable인터페이스를 사용해서 진행했다.
** 각각의 경우 인스턴스 생성방법이 다르므로 알아두자.
-start()
- 쓰레드를 생성한 후 start()를 호출해야 쓰레드가 실행된다.
- 쓰레드 작업이 한번 더 진행되어야 한다면 새로운 쓰레드를 한번 더 생성한 다음 start() 호출해야 한다.
-start() & run()
- main메서드에서 쓰레드의 start() 호출
- start()는 새로운 쓰레드 생성, 쓰레드가 작업하는데 사용될 호출스택 생성
- 생성된 호출스택에 run() 호출 -> 쓰레드가 독립된 공간에서 작업 수행
- 호출스택이 2개 -> 스케줄러가 정한 순서에 의해 진행된다.
-싱글쓰레드 & 멀티쓰레드
- 하나의 쓰레드로 2개의 작업을 수행한 시간 : T1
- 2개의 쓰레드로 2개의 작업을 수행한 시간 : T2
- T1과 T2는 거의 비슷하다.
- 솔직히 멀티쓰레드가 context switching 때문에 좀 더 걸린다.
- 단순히 CPU만 사용하는 계산작업은 싱글쓰레드가 더 효율적
-쓰레드의 I/O블락킹
- 서로 다른 자원을 사용하는 작업의 경우 : 멀티쓰레드 프로세스가 더 효율적
- ex) 사용자로부터 입력받는 작업과 화면에 출력하는 작업이 있을 때
- 멀티쓰레드는 하나의 쓰레드가 사용자의 입력을 기다리는 동안 다른 쓰레드가 작업을 처리 가능
- 효율적인 CPU 사용 가능
- 숫자가 줄어드는 동안 아무값을 입력받을 수 있도록 했다.
- 입력을 한다면 결과처럼 나올 것이다.
-쓰레드의 우선순위
- 쓰레드에 우선순위를 정해 실행시간이 달라질 수 있다.
- 범위 : 1~10
- 숫자가 높을수록 우선순위가 높다(10 : 최대우선순위, 1 : 최소우선순위, 5 : 보통우선순위)
- 저 코드에 대한 결과는 컴퓨터마다 달라질 수 있다.
- 자바가 OS독립적이긴 하지만, OS종속적인 부분이 몇 가지 있는데, 쓰레드가 그 중 하나이다.
- 즉, 위의 예제는 OS마다 결과가 다르게 나온다.
- OS마다 다른방식으로 스케쥴링하기 때문이다.
- 또 컴퓨터의 성능에 따라서도 다른 결과가 나올 수 있다.
-쓰레드 그룹(Thread Group)
- 서로 관련된 쓰레드를 그룹으로 다루기 위한 것
- 보안상의 이유로 도입된 개념
- 그룹을 지정하지 않으면 자동으로 main쓰레드 그룹에 속하게 된다.
-데몬 쓰레드(daemon thread)
- 일반 쓰레드의 작업을 보조하는 보조적인 역할을 수행하는 쓰레드
- ex) 가비지 컬렉터, 자동저장, 화면자동갱신 등
- 데몬 쓰레드가 생성한 쓰레드는 자동으로 데몬 쓰레드가 된다.
- setDaemon메서드는 반드시 start()를 호출하기 전에 실행되어야 한다.
- 그렇지 않으면 IllegalThreadStateException이 발생
-쓰레드의 상태
상태 | 설명 |
NEW | 쓰레드가 생성되고 아직 start()는 호출되지 않음 |
RUNNABLE | 실행 중 또는 실행 가능 상태 |
BLOCKED | 동기화블럭에 의해 일시정지된 상태 |
WAITING , TIMED_WAITING | - 쓰레드의 작업은 종료X, 실행가능하지 않은 일시정지상태 - TIMED_WAITING은 일시정지시간이 지정된 경우 |
TERMINATED | 쓰레드의 작업 종료 |
-쓰레드의 실행제어
- 쓰레드의 실행을 제어하는 메서드 제공
- 효율적인 프로그래밍 가능하도록 도와준다.
- sleep() : 지정시간동안 멈춤
- interrupt() : 쓰레드의 작업을 멈추라고 요청 , 강제성은 없다.
- suspend(), resume(), stop() : 쓰레드의 실행제어를 하는 가장 손쉬운 방법
- 하지만 교착상태를 일으키기 쉬움 -> 현재는 Deprecated됨
- join() : 다른 쓰레드의 작업을 기다림
- yield() : 다른 쓰레드에게 양보 -> yield() 와 interrupt()를 잘 사용하면 효율적인 실행 가능
-쓰레드의 동기화
- 멀티쓰레드 프로세스에서 고려해야 하는 것
- 한 쓰레드가 특정 작업을 끝마치기 전까지 다른 쓰레드에게 방해받지 않도록 하는 것 필요
- critical section(임계 영역), lock 개념이 도입
- synchronization(동기화) : 한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하도록 막는 것
- synchronized 키워드를 이용한다.
- 메서드를 임계영역으로 지정 OR 특정 영역을 임계영역으로 지정 -> 2가지 방식 존재
- 임계영역에 들어가면 lock(락)을 얻어 작업을 수행 , 벗어나면 lock(락)을 반환.
- synchronized 키워드를 이용하여 작성한 예제이다.
- 주의 : balance의 접근 제어자가 private이다.
- 그래야 값의 변경이 임의로 일어나지 않는다.
-wait() & notify()
- sychronized로 동기화 하면 공유 데이터를 보호할 수 있다.
- 특정 쓰레드가 락을 오랜 시간 유지하면 안된다.
- 그래서 등장한 메서드 wait, notify
- wait() : 쓰레드가 락을 반납하고 기다리게 한다.
- notify() : 작업을 중단했던 쓰레드가 다시 락을 얻어 작업을 진행할 수 있게 한다.
14장. 람다와 스트림
-람다식(Lambda Expression)
- 메서드를 하나의 식으로 표현한 것
- 익명함수(anonymous function)라고도 한다.
-람다식 작성
- 메서드에서 이름과 반환타입 제거
- 매개변수 선언부와 {} 사이에 '->' 추가
- 반환값이 있는 경우 : return문을 생략할 수 있다.
- 매개변수의 타입 : 추론 가능한 경우 생략 (대부분 생략 가능)
-람다식 : 익명클래스의 객체와 동등
-함수형 인터페이스
- 인터페이스를 통해 람다식을 다룰 수 있다.
- 람다식을 다루기 위한 인터페이스 = 함수형 인터페이스
- 함수형 인터페이스는 오직 하나의 추상 메서드만 정의되어 있어야 한다.
- 함수형 인터페이스에 대한 예제이다.
-java.util.function패키지
- 일반적으로 자주 쓰이는 형식의 메서드를 정의
- 가능하면 이 패키지를 이용하는 것이 좋다.
함수형 인터페이스 | 메서드 | 설명 |
java.lang.Runnable | () -> void run() -> () | 매개변수 없음, 반환값 없음 |
Supplier<T> | () -> T get() -> T | 매개변수 없음, 반환값 있음 |
Consumer<T> | T -> void accept(T t) -> () | 매개변수 있음, 반환값 없음 |
Function<T,R> | T -> R apply(T t) -> R | 일반적인 함수 형태 |
Predicate<T> | T -> boolean test(T t) -> boolean | 조건식 표현할 때 사용됨 매개변수 하나, 반환타입은 boolean |
BiConsumer<T,U> | T,U -> void accept(T t, U u) -> () | 2개의 매개변수, 반환값 없음 |
BiPredicate<T,U> | T,U -> boolean test(T t, U u) -> boolean | 조건식 표현하는데 사용 매개변수 2개, 반환타입은 boolean |
BiFunction<T,U,R> | T,U -> R apply(T t, U u) -> R | 2개의 매개변수, 하나의 타입 반환 |
UnaryOperator<T> | T -> T apply(T t) -> T | Function의 자손 매개변수와 결과의 타입이 같다. |
BinaryOperator<T> | T,T -> T apply(T t, T t) -> T | BiFunction의 자손 매개변수와 결과의 타입이 같다. |
- Supplier는 1~100 사이의 임의의 정수 생성
- Consumer는 출력
- Predicate은 조건문 - 짝수인지 확인
- Function은 일의 자리를 없애는 식
-Predicate의 결합
- and(), or(), negate() 로 연결할 수 있다.
- 그에 대한 예제를 표현한 것이다.
-컬렉션 프레임웍과 함수형 인터페이스
- 예제를 보는 것이 이해가 더 빠르다.
-메서드 참조
- 메서드 참조를 이용해서 람다식을 더 간략히 할 수 있다.
- ex) Function<String, Integer> f = (String s) -> Integer.parseInt(s); 일 때
- Function<String, Integer> f = Integer::parseInt; 로 하면 메서드 참조이다.
종류 | 람다 | 메서드 참조 |
static메서드 참조 | (x) -> ClassName.method(x) | ClassName::method |
인스턴스메서드 참조 | (obj x) -> obj.method(x) | ClassName:method |
특정 객체 인스턴스메서드 참조 | (x) -> obj.method(x) | obj::method |
다음으로 스트림이 있는데 스트림은 분량이 많아서 다음으로 넘기겠다.
'JAVA' 카테고리의 다른 글
Java의 정석을 시작하자(6)(2/10) (0) | 2020.02.14 |
---|---|
Java의 정석을 시작하자(5)(2/8) (0) | 2020.02.14 |
Java의 정석을 시작하자(4)(2/7) (0) | 2020.02.13 |
Java의 정석을 시작하자(3)(2/6) (0) | 2020.02.13 |
Java의 정석을 시작하자(2)(2/5) (0) | 2020.02.12 |