스레드 상태 제어

2022. 4. 28. 19:23java/java

*상태 제어

 1) 시행 중인 스레드의 상태를 변경하는 것을 말한다.

 2) 상태 변화를 가져오는 메소드의 종류

 

 

[1] sleep - 주어진 시간동안 일시정지

try {
	Thread.sleep(1000);
} catch(InterruptedExection e) {
	//interrupt() 메소드가 호출되면 실행
}

  1) 얼마 동안 일시 정지 상태로 있을 것인지, 밀리세컨드단위로 지정

  2) 일시 정지 상태에서 interrupt() 메소드가 호출되면 interruptExepction 예외를 발생시켜, 예외처리 코드에서 실행 대       기 상태로 가거나 종료 상태로 갈 수 있도록 한다.

 

[2] yield() - 다른 스레드에게 실행 양보

 

public class ThreadA extends Thread {
	public boolean stop = false;
	public boolean work = true;
	
	@Override
	public void run() {
		while(!stop) {				//stop()메소드는 사용되지 않도록 권장되기 때문에 이런 방식으로 멈춰준다
			if(work) {
				System.out.println("TreadA 작업 내용");
			} else {
				Thread.yield();
			}
		}
		System.out.println("ThreadA 종료");
	}
}

_________________________________________________________

public class ThreadB extends Thread {
	public boolean stop = false;
	public boolean work = true;
	
	@Override
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println("TreadB 작업 내용");
			} else {
				Thread.yield();
			}
		}
		System.out.println("ThreadB 종료");
	}
}

__________________________________________________________

public class YiedExample {

	public static void main(String[] args) {
		ThreadA threadA = new ThreadA();
		ThreadB threadB = new ThreadB();
		
        //번갈아 가며 실행
		threadA.start();
		threadB.start();
		
        //3초뒤 threadA실행 대기
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) { }
		threadA.work = false;
		
        //3초뒤 스레드 둘다 번갈아가며 실행
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) { }
		threadA.work = true;
		
        
        //3초뒤 둘다 종료
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) { }
		threadA.stop = true;
		threadB.stop = true;
	}
}

 

[3] join() - 다른 스레드의 종료를 기다림

 

 1)계산 작업을 하는 스레드가 모든 계산 작업을 마쳤을 때,

   계산 결과값을 받아 이용하는 경우에 주로 사용

 

public class SumThread extends Thread {
	private long sum;

	public long getSum() {
		return sum;
	}

	public void setSum(long sum) {
		this.sum = sum;
	}
	
	@Override
	public void run() {
		for(int i = 1; i <= 100; i++) {
			sum += i;
		}
	}
}

_____________________________________________

public class JoinExample {

	public static void main(String[] args) {
		SumThread sumThread = new SumThread();
		sumThread.start();
		
        //이때 바로 출력하면 sumThread가 계산을 완료하기 전에 출력되므로 엉뚱한 값이 출력됨
		System.out.println("1~100 합 : " + sumThread.getSum());
     
	}
}

______________________________________________

package sec06.exam03_join;

public class JoinExample {

	public static void main(String[] args) {
		SumThread sumThread = new SumThread();
		sumThread.start();
		
		//main스레드를 sumThread가 계산을 완료할 때 까지 실행을 대기시킴
		//얼핏 보기에는 sumThread가 join() 메서드르 호출한 것처럼 보이나 main메서드를 실행시키는 건
		//main스레드!
		try {
			sumThread.join();
		} catch (InterruptedException e) {}
		
		System.out.println("1~100 합 : " + sumThread.getSum());
	}
}

[4] wait(), notify(), notifyAll() - 스레드간 협업

 1) 동기화 메소드 또는 블록에서만 호출 가능한 Object의 메소드

 2) wait()

  -호출한 스레드는 일시 정지가 된다.

  -다른 스레드가 notify() 또는

   notifyAll()을 호출하면 실행 대기 상태가 된다.

 3) wait(long timeout),

     wait(long timeout, int nanos)

   - notify()가 호출되지 않아도 시간이 지나면

     스레드가 자동적으로 실행 대기 상태가 된다.

 4) 두 개의 스레드가 교대로 번갈아 가며 실행해야할 경우에 주로 사용

 

 

public class WorkObject {		// ThreadA와 ThreadB의 공유 객체
	public synchronized void methodA() {			//wait() ,notify()메서드를 실행하려면 동기화!
		System.out.println("ThreadA의 methodA() 작업 실행");
		notify();
		try {
			wait();
		} catch (InterruptedException e) {}
	}
	
	public synchronized void methodB() {
		System.out.println("ThreadB의 methodB() 작업 실행");
		notify();
		try {
			wait();
		} catch (InterruptedException e) {}
	}
}

___________________________________________________________

public class ThreadA extends Thread {
	private WorkObject workObject;
	
	public ThreadA(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i = 0; i < 10; i++) {
			workObject.methodA();
		}
	}
}

___________________________________________________________

public class ThreadB extends Thread {
	private WorkObject workObject;
	
	public ThreadB(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i = 0; i < 10; i++) {
			workObject.methodB();
		}
	}
}

__________________________________________________________

public class WatiNotifyExample {

	public static void main(String[] args) {
		WorkObject sharedObject = new WorkObject();
		
		ThreadA threadA = new ThreadA(sharedObject);
		ThreadB threadB = new ThreadB(sharedObject);
		
		threadA.start();
		threadB.start();
	}
}

 

 

 

'java > java' 카테고리의 다른 글

데몬 스레드  (0) 2022.04.29
콘솔 입출력  (0) 2022.04.28
입력스트림과 출력 스트림 개념(2)  (0) 2022.04.26
스레드 상태  (0) 2022.04.26
동기화 메소드와 동기화 블록  (0) 2022.04.26