프로세스 & 쓰레드와
모던 자바에 대해 알려주신다고 한다
프로세스 작업 단위
프로세스는 “실행 중인 프로그램”을 의미
OS가 프로그램 실행을 위한 프로세스를 할당해줄때 프로세스안에 프로그램 Code와 Data 그리고 메모리 영역(Stack, Heap)을 함께 할당
Memory (메모리 영역)
쓰레드는 프로세스내에서 일하는 일꾼(코드실행의 흐름)
쓰레드의 생성
프로세스가 작업중인 프로그램에서 실행요청이 들어오면 쓰레드(일꾼)을 만들어 명령을 처리
쓰레드의 자원
Java 프로그램 쓰레드는 Java Main 쓰레드부터 실행되며 JVM에 의해 실행
↕️
프로세스 안에서 하나의 쓰레드만 실행되는 것
Java 프로그램의 경우 main()
메서드만 실행시켰을때 이것을 싱글 쓰레드
프로세스 안에서 여러개의 쓰레드가 실행되는 것
멀티 쓰레드 장점
멀티 쓰레드 단점
public class TestThread extends Thread {
@Override
public void run() {
// 쓰레드 수행작업
}
}
main에서
TestThread thread = new TestThread(); // 쓰레드 생성
thread.start() // 쓰레드 실행
run()
메서드에 작성된 코드가 쓰레드가 수행할 작업
public class TestRunnable implements Runnable {
@Override
public void run() {
// 쓰레드 수행작업
}
}
...
Runnable run = new TestRunnable();
Thread thread = new Thread(run); // 쓰레드 생성
thread.start(); // 쓰레드 실행
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
int sum = 0;
for (int i = 0; i < 50; i++) {
sum += i;
System.out.println(sum);
}
System.out.println(Thread.currentThread().getName() + " 최종 합 : " + sum);
};
Thread thread1 = new Thread(task);
thread1.setName("thread1");
Thread thread2 = new Thread(task);
thread2.setName("thread2");
thread1.start();
thread2.start();
}
}
보조적인 역할을 담당하며 대표적인 데몬 쓰레드로는 메모리 영역을 정리해주는 가비지 컬렉터(GC)
우선 순위가 낮다= 다른 쓰레드에 비해 리소스를 적게 할당받는다.
setPriority()
메서드로 설정 가능. Thread thread1 = new Thread(task1);
thread1.setPriority(8);
메인 쓰레드는 system 그룹 하위에 있는 main 그룹에 포함
모든 쓰레드들은 반드시 하나의 그룹에 포함
상태 | Enum | 설명 |
---|---|---|
객체생성 | NEW | 쓰레드 객체 생성, 아직 start() 메서드 호출 전의 상태 |
실행대기 | RUNNABLE | 실행 상태로 언제든지 갈 수 있는 상태 |
일시정지 | WAITING | 다른 쓰레드가 통지(notify) 할 때까지 기다리는 상태 |
일시정지 | TIMED_WAITING | 주어진 시간 동안 기다리는 상태 |
일시정지 | BLOCKED | 사용하고자 하는 객체의 Lock이 풀릴 때까지 기다리는 상태 |
종료 | TERMINATED | 쓰레드의 작업이 종료된 상태 |
현재 쓰레드를 지정된 시간동안 멈추게함
Thread.sleep(ms);
ms(밀리초) 단위로 설정됩니다.interrupt()
를 만나면 다시 실행되기 때문에 InterruptedException이 발생할 수 있습니다.일시정지 상태인 쓰레드를 실행대기 상태로 만들어준다.
!Thread.currentThread().isInterrupted()
로 interrupted 상태를 체크해서 처리하면 오류를 방지
정해진 시간동안 지정한 쓰레드가 작업하는 것을 기다립니다.
시간을 지정하지 않았을 때는 지정한 쓰레드의 작업이 끝날 때까지 기다립니다.
예외처리를 해야합니다.
interrupt()
를 만나면 기다리는 것을 멈추기 때문에 InterruptedException이 발생할 수 있습니다.시간을 지정하지 않았기 때문에 thread가 작업을 끝낼 때까지 main 쓰레드는 기다리게됩니다.
남은 시간을 다음 쓰레드에게 양보하고 쓰레드 자신은 실행대기 상태
한 쓰레드가 진행중인 작업을 다른 쓰레드가 침범하지 못하도록 막는 것을 '쓰레드 동기화(Synchronization)'
동기화를 하려면 다른 쓰레드의 침범을 막아야하는 코드들을 ‘임계영역’으로 설정
임계영역에는 Lock을 가진 단 하나의 쓰레드만 출입이 가능
침범을 막은 코드를 수행하다가 작업을 더 이상 진행할 상황이 아니면, wait() 을 호출하여 쓰레드가 Lock을 반납하고 기다리게 할 수 있다!
wait()
실행 중이던 쓰레드는 해당 객체의 대기실(waiting pool)에서 통지를 기다림
notify()
해당 객체의 대기실(waiting pool)에 있는 모든 쓰레드 중에서 임의의 쓰레드만 통지받음
synchronized 블럭으로 동기화하면 자동적으로 Lock이 걸리고 풀리지만, 같은 메서드 내에서만 Lock을 걸 수 있다는 제약
이런 제약을 해결하기 위해 Lock 클래스를 사용
재진입 가능한 Lock, 가장 일반적인 배타 Lock
특정 조건에서 Lock을 풀고, 나중에 다시 Lock을 얻어 임계영역으로 진입이 가능
읽기에는 공유적이고, 쓰기에는 베타적인 Lock
읽기 Lock이 걸려있으면 다른 쓰레드들도 읽기 Lock을 중복으로 걸고 읽기를 수행
읽기 Lock이 걸려있는 상태에서 쓰기 Lock을 거는 것은 허용X. (데이터 변경 방지)
ReentrantReadWriteLock에 낙관적인 Lock의 기능을 추가
낙관적인 Lock : 데이터를 변경하기 전에 락을 걸지 않는 것
낙관적인 락을 사용하면 읽기와 쓰기 작업 모두가 빠르게 처리
낙관적인 읽기 Lock은 쓰기 Lock에 의해 바로 해제 가능
무조건 읽기 Lock을 걸지 않고, 쓰기와 읽기가 충돌할 때만 쓰기 후 읽기 Lock
자바8!!!대격변....?
함수를 일급 객체로 취급하여 함수의 인자로 전달하거나 결과로 반환할 수 있다.
순수 함수와 불변성을 중요시하는 프로그래밍 패러다임.
함수형 인터페이스의 구현을 간단한 표현으로 작성할 수 있다.
(a, b) -> a + b와 같은 형식으로 표현된다.
데이터의 연속성을 표현하며, 여러 연산을 체이닝하여 복잡한 데이터 처리를 수행한다.
filter(), map(), collect() 등의 함수를 사용하여 데이터를 가공한다.
Null은 자바에서 자주 발생하는 문제점 중 하나이다. 이를 안전하게 처리하기 위해 Optional 클래스가 도입되었다.
Optional을 사용하면 Null 값을 보다 명확하게 처리할 수 있으며, 불필요한 Null 체크를 줄일 수 있다.
Optional.of(), Optional.empty(), Optional.ofNullable() 등의 메서드를 제공한다.
다른강의도 참고 해야겠다...
오늘은 이제 저녁에 특강으로 TIL작성하는 이유와 뭐 이런저런것들의 강의가 있었는데
나는 개발자가 되겠어!할떄부터 작성을 하고 있다보니 어떻게 쓰는지 방법도 뭣도 모르는 상태로 써나간것들이였지만 이젠 좀 더 자세하고 세세하게 정리를 해 나아가며 써봐야겠다는 생각을 하기는 했다. 언제까지 할진 모르지만 내가 스스로를 믿어주지 않는데 누가 나를 믿을것인가.
전반적인 자바 강의를 들었지만 이렇게 속도감있고 빠르게 슈루룩 넘어가는 강의는 정말 드물었던거 같다. 그래서 그런지 아직 잘 감이 안잡히지만 개인 과제가 내일부터 나오니 그것들을 해 나아가면서 한번 제대로 도전해보려한다.