ThreadThread 클래스의 여러 메서드들Thread 우선순위join()interrupt()동기화synchronized 메서드synchronized 블럭deadlockwait() / notify() 메서드를 활용한 동기화 프로그래밍
Thread
- Process : 프로그램이 OS로부터 메모리를 할당받아 실행되면 이를 프로세스라고 함
- thread : process 가 구동이 되려면 cpu를 점유해야 하는데 cpu를 점유하는 단위는 thread
- 하나의 프로세스는 하나 이상의 thread를 가짐
- 실제 작업을 수행 하는 단위가 thread
- context : thread가 자신만의 작업공간을 가짐. 각각의 thread별로 사용하는 변수가 다를테니
- Shared resource : thread가 동시에 공유하는 자원 (Java에서는 static instance)
- 이 자원을 여러 thread에서 동시에 접근할때 문제가 생길 수 있음
- 서로 자원을 차지하려는 race condition이 발생할 수 있음
- critical section : 여러 thread가 공유하는 자원 중 경쟁이 발생하는 부분 ⇒ 동기화가 필요 (일종의 순차적 수행.하게끔 lock을 거는것)
// 첫번째 방법 class MyThread extends Thread{ public void run() { int i; for(i=1; i<200;i++) { System.out.print(i + "\t"); } } } // 두번째 방법 class MyThread implements Runnable{ @Override public void run() { int i; for (i=0; i<200; i++) { System.out.print(i + "\t"); } } }

- thread.start를 하면 Runnable의 상태로 들어가게 됨. 실행가능한 상태
- CPU 배분이 되면 run이 됨
Thread 클래스의 여러 메서드들
Thread 우선순위
- Thread.MIN_PRIORITY ~ Thread.MAX_PRIORITY
join()
- 동시에 두개 이상의 Thread가 실행 될 때 다른 Thread의 결과를 참조하여 실행해야 하는 경우 join() 함수를 사용
- join()함수를 호출한 Thread가 non-runnable 상태가 됨
public class JoinTest extends Thread{ int start; int end; int total; public JoinTest(int start, int end){ this.start = start; this.end = end; } public void run(){ int i; for(i = start; i <= end; i++){ total += i; } } public static void main(String[] args) { JoinTest jt1 = new JoinTest(1, 50); JoinTest jt2 = new JoinTest(51, 100); jt1.start(); jt2.start(); try{ jt1.join(); // main Thread에서 jt1에 join을 호출한것. main Thread가 non Runnable하게됨 jt2.join(); }catch (InterruptedException e) { System.out.println(e); } int lastTotal = jt1.total + jt2.total; System.out.println("jt1.total = " + jt1.total); System.out.println("jt2.total = " + jt2.total); System.out.println("lastTotal = " + lastTotal); } }
interrupt()
- 다른 Thread에 예외를 발생시키는 interrupt를 보낸다
- Thread가 join(), sleep(), wait() 함수에 의해 not-runnable 상태일 때 interrupt() 메서드를 호출하면 다시 runnable 상태가 될 수 있음
동기화

- critical section 은 두 개 이상의 thread가 동시에 접근 하는 경우 문제가 생길 수 있기 때문에 동시에 접근할 수 없는 영역
- semaphore 는 특별한 형태의 시스템 객체이며 get/release 두 개의 기능이 있다.
- 한 순간 오직 하나의 thread 만이 semaphore를 얻을 수 있고, 나머지 thread들은 대기(blocking) 상태가 된다.
- producer consumer문제.. 와 마찬가지로 consume하는 동안 produce가 call 되면 안되는것. 한번에 하나씩
synchronized 메서드
class Bank{ private int money = 10000; // synchronized method 방식 public synchronized void saveMoney(int save) { //...body... } // synchronized block 방식 public void setMoney(int save){ synchronized (this){ // ...body... }
- synchronized method로 구현되면, 이 method가 수행되는 동안 method가 포함된 객체에 lock을 적용하고 다른 곳에서 이 객체에 접근을 불가능하게 만들어줌
synchronized 블럭
- synchronized block 방식은 synchronized 하고 괄호안에 어떤 리소스(객체 변수)에 sync를 걸건지를 정해주면 됨
class Park extends Thread{ public void run() { synchronized (SyncMain.myBank){ System.out.println("start save"); SyncMain.myBank.saveMoney(3000); System.out.println("saveMoney(3000) : " + SyncMain.myBank.getMoney()); } } }
deadlock

- Thread1은 끝나려면 L2의 락이 풀려야 하는데 Thread2는 끝나려면 L1의 락이 풀려야 하는 상황. 서로 Lock을 걸고 있어서 끝날수가 없는 상황을 deadlock
- synchronized 메서드에서 다른 synchronized메서드 호출하지마라!
- 자바에서는 deadlock에 대한 해결책이 없음. 그래서 호출 중복으로 하지마라
wait() / notify() 메서드를 활용한 동기화 프로그래밍
- 리소스가 어떤 조건에서 더 이상 유효하지 않은 경우 리소스를 기다리기 위해 Thread가 wait() 상태가 됨
- wait() 상태가 된 Thread는 notify() 가 호출 될 때까지 기다림
- 유효한 자원이 생기면 notify()가 호출되고 wait() 하고 있는 Thread 중 무작위로 하나의 Thread를 재시작 하도록 한다.
- notifyAll() : wait() 하고 있는 모든 Thread가 재시작
- 이 경우 유효한 리소스만큼의 Thread만이 수행될 수 있고 자원을 갖지 못한 Thread의 경우는 다시 wait() 상태로 만든다.
- 자바에서는 notifyAll() 메서드의 사용을 권장한다.