본문 바로가기

웹 개발/Java

[Web_JAVA] 39

● Thread 종료 방법

1. 필드에 boolean 타입의 변수를 선언하고,

    run() 안에 있는 반복문에 해당 변수가 true일 경우 break를 할 수 있도록 설계한다.

 

2. sleep(), wait() 그리고 join() 등의 메소드를 통해 쓰레드 일시정지 상태가 되면

    Thread객체.interrupt()를 사용하여 InterruptedException을 발생시킨다.

    이 때 일시정지를 시킨 메소드 부분의 catch를 통해 예외를 잡아주고 원하는 문장을 작성하면 된다.

 

3. 쓰레드를 일시정지 하는 코드가 없을 경우 Thread.interrupted()의 상태를 확인한다.

    Thread객체.interrupt()를 사용하면 Thread.interrupted()의 상태는 true로 변경되고,

    만약 Thread.interrupted()를 두 번 사용하면 두 번째부터는 false 상태로 리턴된다.

 

4. System.exit(0)를 사용하면 프로세스 종료(전체 쓰레드 종료)

 

 

 


 

실습(Thread 종료(1))

※ 문제는 {[Web_JAVA] 38}의 Bakery를 활용한다.

1. 방법1

- BreadMakerjava

public class BreadMaker implements Runnable{

	private boolean exit;
	
	public boolean isExit() {
		return exit;
	}

	public void setExit(boolean exit) {
		this.exit = exit;
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			if(exit) {break;}
			.......
		}
	}
 
}

 

 

- Bakery.java

public class Bakery {
	public static void main(String[] args) {
	......

		while(true) {

			if(choice == 0) {
				......
			} else {
				// 쓰레드가 실행 중에 종료시키면 비정상 종료가 되므로
				// 멈춘 상태에서 종료시키는 기술이 필요하다.
				maker.setExit(true);
				break;
			}
		}

	}
}

 

 

 

2. 방법2

- Bakery.java

public class Bakery {
	public static void main(String[] args) {
	......

		while(true) {

			if(choice == 0) {
				......
			} else {
				// 프로세스 종료(전체 종료)
				System.exit(0);
				break;
			}
		}

	}
}

 

 

 

3. 결과

- [나가기] 버튼 클릭 시 바로 종료된다.

 

 

 

 

실습(Thread 종료(2))

※ 문제

- 종료 버튼을 클릭했을 때 바로 종료된다.

 

1. ThreadTest.java

- 방법 1 : sleep() 메소드 사용

public class ThreadTest implements Runnable{

	@Override
	public void run() {
		while(true) {
			System.out.println("실행중...");
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {break;}
			
		}
	}
	
}

 

 

- 방법 2 : Thread.interrupted() 상태 확인

public class ThreadTest implements Runnable{

	@Override
	public void run() {
		while(true) {
			System.out.println("실행중...");
			
			// 쓰레드가 일시정지 하는 코드가 없을 경우 interrupted()를 사용한다.
			if(Thread.interrupted()) {  // 현재 Thread가 종료된 상태라면
				break;
			}
			
		}
	}
	 
}

 

 

 

2. ThreadMain.java

import javax.swing.JOptionPane;

public class ThreadMain {
	public static void main(String[] args) {
		
		Thread t = new Thread(new ThreadTest());
		String[] btns = {"계속하기", "종료"};
		
		t.start();
		
		// btns의 인덱스 번호가 1일 때
		if(JOptionPane.showOptionDialog(null, "", "", JOptionPane.DEFAULT_OPTION,
				JOptionPane.PLAIN_MESSAGE, null, btns, null) == 1) {
			t.interrupt();
		}
		
	}
}

 

 

 

3. 결과

- 대화상자의 {종료} 버튼을 클릭하면 종료된다.

 
대화상자

 

결과(바로 종료)

 

 

 

 

 

실습(Thread)

- 주식 매도 프로그램

 

1. Bank.java(implements Runnable)

- 필요한 변수 선언

// 통장
int money;

// 변환 투자금(After)
int stockMoney = 0;

// 투자금(Before)
int depositMoney = 0;

 

 

- 투자액

public void deposit(int money) {
	this.money += money;
}

 

 

- 매도

public void sell() {
	this.money += stockMoney;
}

 

 

- 주식

public boolean stock() {
	Random r = new Random();
	int rating = 0;
	
	if(r.nextInt(100) == 0) {  // 1% 확률
		stockMoney = 0;
		return false;
	}
	
	// 1 ~ 30
	rating = r.nextInt(30) + 1;
	
	// 10% 확률로 하한가
	if(r.nextInt(10) == 0) {
		rating *= -1;  // -를 붙여주기 위해 -1을 곱해준다.
	}
	
	// 원금에서 수익률만큼 갱신
	// (ex) 수익률 +30%
	// rating = 30, (100 + 30) * 0.01
	stockMoney *= (100 + rating) * 0.01;
	
	return true;
	 
}

 

 

- run() 재정의

@Override
public void run() {
	
	money -= depositMoney;
	
	while(true) {
		if(!stock()) {
			System.out.println("상장이 폐지되었습니다.");
			break;
		}
		
		System.out.print(stockMoney + "원(");
		
		// (700000 - 600000) / 600000.0 * 100
		// 100000 / 600000.0 * 100
		// 0.167 * 100
		// 16.7%
		System.out.println((stockMoney - depositMoney) / (double)depositMoney * 100 + "%)");
		 
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			System.out.println("=====================================");
			System.out.println("주식 전 투자 금액 : " + depositMoney + "원");
			System.out.println("주식 후 투자 금액 : " + stockMoney + "원");
			System.out.println("수익률 : " + (stockMoney - depositMoney) / (double)depositMoney * 100 + "%");
			System.out.println("=====================================");
			break;
		}
		
	}
	
}

 

 

 

2. StockMarket.java

import java.util.Scanner;
import javax.swing.JOptionPane;

public class StockMarket {
	public static void main(String[] args) {
		
		int choice = 0;
		Bank user = new Bank();
		Thread t = new Thread(user);
		String[] btns = {"매도하기", "나가기"};
		Scanner sc = new Scanner(System.in);
		
		System.out.print("투자액 : ");
		user.depositMoney = sc.nextInt(); 
		user.stockMoney = user.depositMoney;
		
		t.start();
		
		while(true) {
			choice = JOptionPane.showOptionDialog(null, "", "", JOptionPane.DEFAULT_OPTION,
					JOptionPane.PLAIN_MESSAGE, null, btns, null);
			
			if(choice == 1) {  // 나가기
				System.exit(0);
			}
			
			if(choice == 0) {  // 매도하기
				t.interrupt();
				try {t.join();} catch (InterruptedException e) {;}
				user.sell();
				break;
			}
			
		}
		
	}
}

 

 

결과(대화상자)

 

결과(매도하기)

 

결과(나가기)

 

 

 

 

'웹 개발 > Java' 카테고리의 다른 글

[Web_JAVA] 41  (0) 2022.03.27
[Web_JAVA] 40  (0) 2022.03.26
[Web_JAVA] 38  (0) 2022.03.24
[Web_JAVA] 37  (0) 2022.03.23
[Web_JAVA] 36  (0) 2022.03.22