프로세스
프로세스란 단순히 실행 중인 프로그램을 의미합니다. 즉, 사용자가 작성한 프로그램이 운영체제에 의해 메모리 공간을 할당받아 실행 중인 것을 말합니다. 이러한 프로세스는 프로그램에 사용되는 데이터와 메모리 등의 자원 그리고 스레드로 구성됩니다.
스레드
스레드란 프로세스 내에서 실제로 작업을 수행하는 주체를 의미합니다. 모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행합니다. 또한, 두 개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스(multi-threaded process)라고 합니다.
프로세스 진행 방식
선점형 방식
우선순위 순서대로 자원(메모리)을 할당받아 진행되는 방식을 말합니다. 이 방식은 기아 현상이 발생될 가능성이 있습니다.
※ 기아 현상 : 어떠한 우선 순위로 작업을 처리할 때 우선순위가 낮은 작업은 영원히 처리되지 않는 문제
시간분할 방식
시간을 동일하게 배분하여 골고루 실행될 수 있도록 진행하는 방식을 말합니다. 기존의 선점형 방식에서 우선순위가 낮아 오래 기다린 프로세스에게 우선순위를 높여주는 방식으로 운영체제가 제공하는 주요기능 중 하나입니다.
스레드의 생명주기
- New
- Runnable
- Running
- Terminated
- Blocked
1. New
객체를 생성합니다. 스레드가 만들어진 상태로 아직 start() 메서드가 호출되지 않은 상태입니다.
2. Runnable
실행대기 상태로 스레드가 실행되기 위한 준비단계입니다. 코드 상에서 start() 메서드를 호출하면 run() 메서드에 설정된 스레드가 Runnable 상태로 진입합니다.
3. Running
CPU를 점유하여 실행하고 있는 상태이며 run() 메서드는 JVM만이 호출 가능합니다. Runnable에 있는 여러 스레드 중 우선 순위를 가진 스레드가 결정되면 JVM이 자동으로 run() 메서드를 호출하여 스레드가 Running 상태로 진입합니다.
4. Terminated
Running 상태에서 스레드가 모두 실행되고 난 후 완료 상태입니다. run() 메서드 완료시 스레드가 종료되며, 그 스레드는 다시 시작할 수 없게 됩니다.
5. Blocked
일시 정지 상태로 사용하고자 하는 객체의 Lock이 풀릴 때까지 기다리는 상태입니다. wait() 메서드에 의해 Blocked 상태가 된 스레드는 notify() 메서드가 호출되면 Runnable 상태로 갑니다. sleep(time) 메서드에 의해 Blocked 상태가 된 스레드는 지정된 시간이 지나면 Runnable 상태로 갑니다.
실습
실습 1
package class01;
// 이미 JAVA에서 구현한 Thread 클래스를 가져다가 사용
// 코드를 재사용할 예정
// => 상속
class Th01 extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread 01 " + i);
}
}
}
class Th02 extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread 02 " + i);
}
}
}
public class Test01 {
public static void main(String[] args) {
Th01 t1 = new Th01(); // 생성
// 생성이되면, 즉시 대기상태가 됨
Th02 t2 = new Th02();
// Thread t3 = new Thread();
t1.start(); // 스레드 객체야, 일해!
t2.start(); // -> run()메서드를 실행시킴
// 메모리를 먼저 할당받는 쪽이 먼저 실행
// start()로 인해 run()을 수행하게되고,
// 주어진 run()을 다 수행하게되면
// 데드상태가 됨
// 스레드 객체들은 현재 독립적으로 일을 수행하고있구나!
// 5개 남은 상품
// t1(사용자1) -> 장바구니에 3개담음
// t2(사용자2) => 5개를 즉시 구매
// 스레드 생명주기(라이프사이클)
// 생성 -> 대기 -> 수행 -> 데드
// 블록 : 자원(메모리)을 할당받지 못하도록 막아둔상태
for (int i = 1; i <= 10; i++) {
System.out.println(i);
try {
Thread.sleep(1000); // 1000 == 1초
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
실습 2
package class02;
// 동기화
// : 공유자원을 어떤 스레드가 점유하고있을때,
// 다른 스레드의 접근을 막는 것
// ex) 티켓, 계좌, ...
class Person extends Thread {
Ticketting t = new Ticketting();
// thread.start() -> run()메서드가 수행
@Override
public void run() {
t.pay();
}
}
class Ticketting { // 사람들이 공유자원인 티켓을 구매하는 로직
static int ticket = 2; // 공유자원, 클래스변수
synchronized void pay() { // synchronized -> 동기화
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "구매성공!");
ticket--;
} else {
System.out.println(Thread.currentThread().getName() + "구매실패ㅠㅠ...");
}
System.out.println("남은티켓: " + ticket);
}
}
public class Test01 {
public static void main(String[] args) {
Person p = new Person();
Thread t1 = new Thread(p, "홍길동");
Thread t2 = new Thread(p, "아무무");
Thread t3 = new Thread(p, "티모");
t1.start();
t2.start();
t3.start();
}
}
GitHub
https://github.com/Qkrwnsgus0522/Java