프로세스와 쓰레드
멀티쓰레드의 장단점
쓰레드의 구현과 실행
쓰레드의 실행 - 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 를 활용하여 구별할수 있다.
출처 : 남궁성의 정석코딩
'Java의 정석' 카테고리의 다른 글
14장. 스트림(Stream) (0) | 2023.02.23 |
---|---|
14장. 람다식, 메서드참조 (0) | 2023.02.23 |
12장. 어노테이션, 메타 어노테이션,타입 정의 및 요소 (0) | 2023.02.19 |
12장. 제네릭 - 와일드카드, 메서드, 제네릭형변환 (0) | 2023.02.18 |
12장. 제네릭스(Generics), 타입 변수,Iterator<E>, 제약 (0) | 2023.02.17 |