프로세스와 쓰레드


멀티쓰레드의 장단점

 


쓰레드의 구현과 실행

 


쓰레드의 실행 - start()


start() 와 run()       -        (run을 구현했는데, 왜 start로 실행하지?)


main쓰레드


싱글쓰레드와 멀티 쓰레드


싱글 쓰레드와 멀티 쓰레드의 I/O 블락킹 ( 입출력시 작업중단 )

 


쓰레드의 우선순위


쓰레드 그룹


데몬 쓰레드

 


쓰레드의 상태

 


쓰레드의 실행제어


(static) sleep()

 


interrupt()

 


join()


yield()


쓰레드의 동기화 (synchronization)


synchronized를 이용한 동기화


wait()과 notify()

import java.util.ArrayList;

class Customer2 implements Runnable{
	private Table2 table;
	private String food;
	
	public Customer2(Table2 table, String food) {
		this.table = table;
		this.food = food;
	}
	
	public void run() {
		while(true) {
			try {
				Thread.sleep(100);
			}catch (InterruptedException e) {}
			String name = Thread.currentThread().getName();
			
			table.remove(food);
			System.out.println(name + " ate a " + food);
		}
	}
}

class Cook2 implements Runnable{
	private Table2 table;
	
	Cook2(Table2 table){
		this.table = table;
	}
	
	public void run() {
		while(true) {
			int idx = (int)(Math.random() * table.dishNum());
			table.add(table.dishNames[idx]);
			try {
				Thread.sleep(10);
			}catch (InterruptedException e) {}
		} // while end
	} // run end
} // Cook2 end

class Table2{
	String[] dishNames = { "donut", "donut", "burger" };
	final int MAX_FOOD = 6;
	private ArrayList<String> dishes = new ArrayList<>();
	
	public synchronized void add(String dish) { //synchronized 추가
		while(dishes.size() >= MAX_FOOD) {
			String name = Thread.currentThread().getName();
			System.out.println(name + " is waiting.");
			try {
				wait(); // Cook 쓰레드를 기다리게한다. (테이블에 음식이 꽉참)
				Thread.sleep(500);
			}catch (InterruptedException e) {}
		}
		dishes.add(dish); 
		notify(); // 기다리고 있는 cust를 깨우기 위함.
		System.out.println("Dishes : " + dishes.toString());
	}
	
	public void remove(String dishName) {
		synchronized (this) {
			String name = Thread.currentThread().getName();
			
			while(dishes.size()==0) {
				System.out.println(name + " is waiting.");
				try {
					wait(); // CUST쓰레드를 기다리게 한다.
					Thread.sleep(500);
				}catch (InterruptedException e) {}
			}
			
			while(true) {
				for (int i = 0; i < dishes.size(); i++) {
					if(dishName.equals(dishes.get(i))) {
						dishes.remove(i);
						notify(); //잠자고 잇는  Cook을 깨우기 위함/
						return;
					}
				}
				try {
					System.out.println(name + " is waiting.");
					wait(); // CUST쓰레드를 기다리게 한다.
					Thread.sleep(500);
				}catch (InterruptedException e) {}
			} // while end
		} // synchronized end			
	} // remove end
	
	public int dishNum() { 
		return dishNames.length; 
		}
} // class Table2 end

public class ex13_15 {
	public static void main(String[] args) throws InterruptedException {
		Table2 table = new Table2(); 
		new Thread(new Cook2(table), "COOK").start();
		new Thread(new Customer2(table, "donut"),  "CUST1").start(); // 도넛만 먹는 손님
		new Thread(new Customer2(table, "burger"), "CUST2").start(); // 버거만 먹는 손님
		Thread.sleep(2000);
		System.exit(0);
	}
}

 

 

wait()으로 waiting pool 대기실로 보낸 요리사, 손님 중 누굴깨울지 notify()로는 불명확
Lock & Content 를 활용하여 구별할수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


출처 : 남궁성의 정석코딩

https://www.youtube.com/@MasterNKS

+ Recent posts