[JAVA] ch.18 스레드
멀티태스킹
- 동시에 두 가지 이상의 작업을 처리하는 것
- 멀티태스킹을 위한 두 가지 도구 : 프로세스, 스레드 (하나의 프로세스는 적어도 한개의 스레드를 가짐)
프로그램
- 파일이 존재하지만 아직 메모리에 올라가 있지 않은 상태
- 실행되지 않은 코드의 집합
- os의 메모리에 올라간 것
프로세스
- 프로그램을 실행하는 순간 메모리에 올라가고 동작하는 상태의 프로그램
- 독립적으로 메모리에 등록된다.(스레드가 여러 개) => 여러 개의 프로그램을 동시 실행 가능
- 각각의 프로세스들은 독립적으로 등록되어 서로 간섭할 수 없다.
- 1개의 스레드를 가지면 구동 스레드라고 한다.
스레드
- 프로세스 내부에 존재하면서 실행 흐름을 나타내는 것
- 스레드는 순서가 없이 작업한다.
- 멀티스레드 : 여러 개의 스레드를 이용해 동시에 작업을 수행
- 사용방법
1. Thread 클래스를 상속해 run()메서드 구현
MyThread thread = new MyThread();
public class MyThread extends Thread{
//스레드가 시작(.start())되면 자동으로 실행되는 메서드
public void run() {
int sum = 0;
for(int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
String threadName = Thread.currentThread().getName();
System.out.println(threadName);
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
//이름부여
thread.setName("더하기");
//스레드 시작
thread.start();
//살아있는지 확인
System.out.println(thread.isAlive());
}
}
- 직접 생성한 스레드는 Thread-n이라는 이름으로 자동 설정된다.
- setName() //이름을 변경할 때
- getName() //이름을 호출할 때
2. Runnable 인터페이스 구현( +람다식 사용)
-Runnable 인터페이스는 추상메서드 run() 하나 만을 가짐
Thread th = new Thread(Runnable을 상속한 인스턴스);
-Runnable을 상속해 만든 객체는 Thread객체에 넣어서 실행해야함
public class Flag implements Runnable{
@Override
public void run() {
for(int i = 0; i < 10; i++) {
if(i % 2 == 0) {
System.out.println("백기 올려");
}
else {
System.out.println("청기 올려");
}
}
}
}
public class FlagMain {
public static void main(String[] args) {
Flag flag = new Flag();
Thread thFlag = new Thread(flag);
thFlag.start();
//익명 클래스 람다식으로 구현
Runnable rn = () -> {
for(int i = 1; i < 10; i++) {
if(i % 2 == 1) {
System.out.println("백기 올려!");
}
else {
System.out.println("청기 올려!");
}
}
};
Thread thFlag2 = new Thread(rn);
thFlag2.start();
}
}
- thread.start() //스레드 시작
스레드 동기화(synchronized)
- 여러 스레드가 하나의 공유 데이터에 동시에 접근하지 못하도록 스레드의 실행을 제어하는 것
- 임계 영역 : 멀티 스레드 프로그램에서 단 하나의 스레드만 처리할 수 있는 영역
- 동기화 처리 : 하나의 스레드가 임계영역에 진입할 때 락을 걸어 다른 스레드가 수행되지 못하게 하고 작업이 종료되면 락을 풀어 다른 스레드가 작업하도록 하는 것
메서드 동기화 처리
- 메서드 이름 앞에 synchronized 키워드를 붙인다.
- 해당 메서드 전체 동기화 => 메서드 처리 시간이 길어지면 성능이 떨어진다.
- 순서대로 처리하진 않지만 서로 간섭할 수 없다.
public synchronized void add() ..
블록 동기화 처리
- 특정 영역만 동기화 처리
- 실제 실행하는 스레드의 일부분을 동기화하여 처리하는 방법
synchronized(객체명)
- 공유 중인 객체를 소괄호에 명시
스레드 상태
- 스레드 상태 확인 : Thread.State
상태 | 상수 | 설명 |
생성 | NEW | 스레드 객체가 생성되었지만 start() 메서드가 호출되지 않은 상태 |
대기 | RUNNABLE | 실행 대기 또는 실행 상태 언제든지 갈 수 있는 상태(실행 직전) |
일시정지 | WATING | 다른 스레드가 종료될 때까지 대기하는 상태(시간x) |
TIMED_WATING | 주어진 시간 동안 대기하는 상태 | |
BLOCKED | 락이 풀릴 때까지 대기하는 상태 | |
종료 | TERMINATED | 수행을 종료한 상태 |
- wait() : 스레드 대기
- notify : 대기 중인 스레드를 다시 동작 시킴
- sleep() : 주어진 시간 동안 스레드를 정지시키는 메서드