24.05.30
#프로세서
실행 중인 프로그램
#멀티프로세서
동시에 여러 프로그램이 실행되는 것
#쓰레드
프로그램 안에서 실행 중인 메소드
#멀티 쓰레드
프로그램 안에서 여러개의 메소드가 동시다발로 동작하는 것
#자바에서는 멀티 쓰레드 프로그래밍을 위하여
Thread 클래스와 Runnable 인터페이스를 이용 할 수 있다!
쓰레드가 해야하는 일은 run()메소드를 오버라이딩해서 그 안에 쓰고,
쓰레드를 동작시키기 위해서는 start()메소드를 호출한다
쓰레드를 가동시키기 위해서 start()를 호출해야하는데 run()을 호출하면 ?
=> 오류가 난다? X
=> 쓰레드가 가동되지 않고, 일반 메소드처럼 동작함
class Hello implements Runnable{
public void run() {
.............
}
}
Hello h = new Hello();
(new Thread(h)).start();
=> 직접 start 호출 불가. Thread 통해서 start 호출해야함
#Thread 우선순위 설정
필요하다면 우선순위 설정 가능
가급적 다른것 보다 먼저 해줘~ 라는거지 항상 더 빨리되는거 아님
ex ) a.setPriority(Thread.MAX_PRIORITY)
#임계영역
두 개 이상의 쓰레드가 자원을 공유할때 한번에 하나의 쓰레드에게만 접근 허용하는 영역
자바에서는 그러한 동작을 하는 메소드 이름 / 그런 기능을 하는 블럭{} 앞에 synchronized 키워드 붙이면
자동으로 임계영역이 돼서 한번에 하나의 쓰레드에게만 접근 허용
5명이 1000원씩 10번 입금하면
50000원이 되어야 하는데 이상함
공유자원에 두 개 이상의 쓰레드가 한번에 접근해서 이런현상이 있을 수 있음
한번에 하나의 쓰레드에게만 접근을 허용하려면 임계영역을 설정해야함
자바에서는 임계영역설정을 위하여 메소드 이름 앞에 synchronized 키워드를 붙여줌
쓰레드를 가동시키면 가능한 동시다발로 공평하게 실행 되게 스케줄링 해줌
만약 두 개의 객체가 반드시 일대일로 동작하도록 하려면 쓰레드 사이의 통신을 이용할 수 있음
#쓰레드 사이의 통신
두 개의 쓰레드가 반드시 1:1로 동작하게 하려면 쓰레드 사이의 통신이 필요함
ex) 생산자, 소비자 -> 생산 되어야 소비 일어나고, 소비 일어나야 생산 -> 둘 사이에 생산, 소비 됐는지 서로 통신 필요
생산자는 소비가 일어날때까지 기다렸다가 소비되면 새로운 제품을 생산하고 소비자는 생산이 일어날때 가지 기다렸다가 새로운게 생산되면 소비가 일어나도록 1:1로 동작할 수 있음
쓰레드 통신 위해 Obejct와 wait, notify 이용
내가 일 완료될때까지 기다리게 위해서 wait 메소드 이용
일 끝나서 상대 깨울땐 notify 를 이용
import java.util.Random;
//생산자와 소비자가 공유할 자원인 "제품"클래스 만들기
//새로운 정수를 제품이라고 가정
public class Product {
// 제품을 위한 정수형 변수를 선언
// 생산자는 이 정수를 계속하여 새롭게 만들어 주고
// 소비자는 이 정수를 계속하여 가져다 쓰도록 합니다.
int number;
// 새 제품이 생산되었는지 판별하기 위한 변수
// 생산자는 새 제품을 생산한 다음 isNew에 true를 저장
// 소비자는 제품을 소비한 후에 isNew에 false를 저장
boolean isNew;
// 생산자가 새 제품을 생산하기 위한 메소드
// 생산자가 새 제품을 만들고 있는동안 소비자는 접근을 못해야하므로
// 임계영역 설정을 위해 synchronized 키워드
public synchronized void makeNumber() {
try {
// 제품이 소비될때까지 기다리기
while( isNew == true ) {
wait();
}
// 새 제품을 만들기
Random r = new Random();
number = r.nextInt(100) + 1;
// 생산된 제품을 출력
System.out.println("생산자가 생산함==>" + number);
// 새 제품을 만들었다고 표시
isNew = true;
// 대기중인 소비자를 깨우기
notify();
}catch (Exception e) {
// TODO: handle exception
}
}
// 소비자가 사용하는 메소드
public synchronized int useNumber() {
int n = 0;
try {
//생산자가 새로운 제품을 생산할 때 까지 기다리기
while(isNew == false) {
wait();
}
//제품을 소비
n = number;
System.out.println("소비자가 소비함:"+n);
//소비했다는 표시
isNew = false;
//대기중인 다른 쓰레드(생산자)를 깨우기
notify();
}catch (Exception e) {
// TODO: handle exception
}
return n;
}
}
// 생산자 클래스를 만들기
// 소비자와 상관없이 계속하여 새로운 제품을 생산케 하기위하여
// Thread클래스를 상속받아 멀티쓰레드가 가능하도록 하기
public class Producer extends Thread {
//제품을 맴버변수로 선언
private Product product;
// 생성시에 제품을 매개변수로 전달받아 초기화
// 이 제품이 소비자와 공유하는 자원
public Producer(Product product) {
this.product = product;
}
//생산자 쓰레드가 해야 할 일을 run을 오버라이딩 하여 써주기
public void run() {
// 10개의 새로운 제품을 생산하도록 합니다.
for(int i=1; i<=10; i++) {
try {
product.makeNumber();
Thread.sleep(100);
}catch (Exception e) {
}
}
}
}
// 소비자 클래스
// 생산자와 상관없이 계속하여 제품을 소비하도록 하기 위해 멀티쓰레드가 되게 하기
public class Consumer extends Thread {
//생산자와 제품을 공유하기 위하여 맴버변수로 제품을 선언
private Product product;
//생성시에 제품을 매개변수로 전달받아 초기화 합니다.
public Consumer(Product product) {
this.product = product;
}
// run을 오버라이딩 하여 소비자가 해야할 일을 써주기
public void run() {
for(int i=1; i<=10; i++) {
product.useNumber();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public class ManTest {
public static void main(String[] args) {
Product product = new Product();
Producer producer = new Producer(product);
Consumer consumer = new Consumer(product);
producer.start();
consumer.start();
}
}