개념
Process
실행 중인 프로그램을 의미함. 즉, 사용자가 작성한 프로그램이 운영체제에 의해 메모리 공간을 할당받아 실행 중인 것을 말함. 이 프로세스는 프로그램에 사용되는 데이터, 메모리 등의 자원과 스레드로 구성됨.
Thread
스레드란 프로세스 내에서 실제로 작업을 수행하는 주체를 의미. 모든 프로세스에는 한 개 이상의 스레드가 존재. 한 개의 스레드를 가질 경우 싱글 스레드, 두 개 이상의 스레드를 가지는 프로세스를 멀티스레드라고 함.
- 비용 : 하나의 새로운 프로세스 생성 > 하나의 새로운 스레드 생성
- 장점 : 시스템 자원보다 효율적으로 사용 가능, 사용자에 대한 응답성 향상, 작업이 분리되어 코드가 간결해짐.
- 단점 : 동기화(사건이나 시간을 같게 함), 교착상태, 각 스레드가 고르게 실행되는 등 프로그래밍 시 고려해야 할 사항이 많음.


*멀티 스레드의 경우 동일하게 실행되는 것 같지만 실제로는 알 수 없음.
*멀티 스레드가 싱글 스레드보다 시간이 더 걸림. context switch가 발생하기 때문.
구현과 실행
방법 ❶ Thread 클래스 상속
자바는 단일 상속만 가능하기 때문에 Thread 클래스를 상속받을 경우 다른 클래스 상속이 어렵기 때문에 잘 사용하지 않음.
방법 ❷ Runnable 인터페이스 구현
Runnable 클래스를 implements하기 때문에 extends는 여전히 가능하여 좀 더 유연하게 사용할 수 있음.
start()
- 스레드를 생성한 후에 start()를 호출해야 스레드가 작업을 시작함.
- OS 스케줄러가 실행순서를 결정, start했다고 즉시 실행되지 않음. 먼저 start했다고 먼저 시작되지 않음.
- start() 호출 → 새로운 run() 호출 → start() 역할 끝. run()은 main()과 독립적으로 생성, 수행됨.

예외 처리 - try catch
try문안의 수행할 문장들에서 예외가 발생하지 않는다면 catch문 다음의 문장들은 수행이 되지 않음. 하지만 try문안의 문장들을 수행 중 해당 예외가 발생하면 예외에 해당하는 catch문이 수행됨.

main 스레드와 상태제어 (join)
- 실행 중인 사용자 스레드가 하나도 없을 때 프로그램은 종료됨. 다만, run() 스레드 등 다른 스레드가 존재할 경우 main 스레드가 종료되어도 프로그램은 종료되지 않음.
- join()메소드는 스레드가 멈출 때까지 기다리게 함.
sleep, join 등 메소드 자체가 exception 을 throw 하는 메소드는 try, catch를 이용하여 예외처리를 해야 함.
우선순위
작업 중요도에 따라 스레드의 우선순위를 다르게 하여 특정 스레드가 더 많은 작업 시간을 갖게 할 수 있음.

- getPriority()와 setPriority() 메소드를 통해 스레드의 우선순위를 반환하거나 변경할 수 있음.
- 스레드의 우선순위는 1~10까지이며, 숫자가 높을수록 우선순위 또한 높아짐.
스레드의 우선순위는 비례적인 절댓값이 아닌 상대적인 값임. 무조건 우선순위가 높다고 더 빨리 끝나지 않음.
데몬 스레드
- 멀티태스킹 운영 체제에서 데몬은 사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말함.
- 일반 스레드의 작업을 돕는 보조 역할 수행.
- 일반 스레드가 종료되면 자동으로 종료됨.
- ex) 가비지 컬렉터, 자동저장, 화면 자동갱신
사용법
- boolean isDaemon() - 스레드가 데몬 스레드라면 true를 반환.
- void setDaemon(boolean on) - 스레드로 데몬 스레드로 변경. 매개 변수 on을 true로 지정하면 데몬 스레드가 됨.
- setDaemon(boolean on)은 반드시 start()를 호출하기 전에 실행되어야 함.
인간과 컴퓨터
Counter와 Printer
스레드를 이용한 매수, 매도 프로그램
Seller와 Buyer 클래스를 스레드로 만들었다. 따라서 메인이 흘러가면서 동시에 매도, 매수가 이뤄지도록 했다
- 미해결 : 동기화 부분 해결하기
- 생성자 : 생성자란 인스턴스가 만들어질 때 호출되는 함수임.
생성자 이름은 클래스 이름과 일치해야 함. 또한 void와 같은 return 불가능.
- Synchronized : 여러 개의 스레드가 한 개의 자원을 사용하고자 할 때, 데이터를 사용하고 있는 스레드를 제외한 나머지 스레드들은 데이터에 접근 할 수 없도록 막는 역할.
한 시점에 오직 하나의 스레드만이 동기화된 인스턴스 메소드를 실행할 수 있음.
너무 남발하면 오히려 프로그램 성능 저하를 일으킬 수 있음.
- random.nextln() : 파라미터를 사용해서 원하는 범위 내의 양수 값을 가져올 수 있음.
마치며
스레드는 프로그램, 프로세스, 메모리 영역 등 컴퓨터와 관련된 내용이 많았다. 그래서 CS가 부족한 나에게 너무 힘든 과정이었다. 알면 알 수록 어려워지는 기분을 느꼈다. 질문을 하려 해도 내가 무엇을 모르는지 모르는 지경까지 도달해서 절망적이었다. 그래도 예시를 하나하나 다시 작성해보면서 감을 익혔다. 분명 이해했던 내용인데 코드로 다시 칠 땐 모르겠다. 그리고 생성자나 인스턴스 등 이미 공부했던 내용이 다시 헷갈렸다. 지금은 헷갈리는 게 덜한데 또 다른 코드를 치면 안 헷갈린다는 장담을 못 하겠다.