Java/Codes

선풍기 (스레드)

펭킹 2022. 3. 24. 13:48

오늘 코드를 검사 맡고, 전에 코드는 실질적인 타이머 기능이 없어서 스레드를 사용해서 구현하도록 조언을 받았다.

그래서 Timer부분은 클래스로 따로 빼서 스레드를 상속받아 구현하였다.

 

package Team3;

import java.util.Scanner;

//싱글턴으로 기능구현
public class Single_Fan_Thread{
	static Single_Fan_Thread fan_s = new Single_Fan_Thread();//싱글턴 패턴 선언
	Single_Fan_Thread getInstance() // 싱글턴 패턴 주소로 반환 <1000번지 주소>
	{
		return fan_s;
	}
	
	//사용할 전역변수 선언
	boolean fan_power;
	String led = "빨강";
	int dan = 1;
	int ang = 90;
	int time = 0;
	
	//문자열과 정수를 사용자로부터 받기위한 스캐너
	Scanner sc = new Scanner(System.in);//문자열
	Scanner ac = new Scanner(System.in);//정수
	
	//Timer클래스 참조변수 선언 (주소값 X)
	Timer tm;
	
	Boolean fan_power()//선풍기 전원 설정
	{
		String ans = sc.nextLine();
		if(ans.equals("Y")||ans.equals("y"))//ans가 y라면
		{
			System.out.println("선풍기를 킬게요\n");
			return fan_power = true;
		}
		else if(ans.equals("N")||ans.equals("n"))//ans가 n라면
		{	
			System.out.println("선풍기를 끌게요\n");
			return fan_power = false;
		}
		else //디폴트값 false
		{
			return fan_power = false;
		}
	}
	
	void LED()//LED색상 변경
	{
		System.out.printf("LED 색상을 선택해주세요. (기본색상은 빨간색입니다.) : ");
		led = sc.nextLine();//사용자에게 색상을 적도록 한다.
		if(led.equals(""))
		{
			led = "빨강";
		}
		System.out.println(led+"으로 선택되었습니다.");
		System.out.println();
	}
	
	void speed()//풍속설정
	{
		System.out.printf("몇단으로 설정 하시겠습니까? (1, 2, 3, 4) : ");
		while(true)
		{
			dan = ac.nextInt();
			if(dan == 1)
			{
				System.out.println(dan+"단으로 변경합니다.");
				System.out.println();
				break;
			}
			else if(dan == 2)
			{
				System.out.println(dan+"단으로 변경합니다.");
				System.out.println();
				break;
			}
			else if(dan == 3)
			{
				System.out.println(dan+"단으로 변경합니다.");
				System.out.println();
				break;
			}
			else if(dan == 4)
			{
				System.out.println(dan+"단으로 변경합니다.");
				System.out.println();
				break;
			}
			else
			{
				System.out.printf("%d은(는) 없는 풍속입니다. 다시 선택해주세요! : ",dan);
			}
		}
	}
	
	void angle()//회전각도 설정
	{
		System.out.printf("각도를 얼마로 설정하시겠습니까? (단, 0도 이하, 180이상은 불가능합니다.) : ");
		while(true)//무한반복
		{
			ang = ac.nextInt();//사용자에게 ang값을 받는다.
			
			if(0<=ang&&ang<=180)//ang이 0도에서 180사이면 
			{
				System.out.println(ang+"도로 설정합니다.\n");
				break;//while문 종료
			}
			else//ang이 0도에서 180사이가 아니라면 
			{
				System.out.printf("%d도는 범위를 벗어납니다. 재입력 해주세요.",ang);
				System.out.println();
			}
		}
	}
	
	void timer()//타이머 설정
	{
		System.out.printf("설정할 시간을 입력하세요. : ");
		time = ac.nextInt();
		
		if(tm == null)//타이머 설정이 안된경우
		{
			tm = new Timer();//Timer 생성
			tm.start();//Timer 실행
			System.out.println(time+"초로 설정되었습니다.");
		}
		else//이미 설정된 타이머가 존재할 경우
		{
			tm.interrupt();//스레드에서 호출되는 즉시 실행을 중지. 이전에 입력한 시간 스레드 즉시정지
			tm = new Timer();//Timer 생성
			tm.start();//Timer 실행
			System.out.println(time+"초로 설정되었습니다.");
		}
	}
	
	public static void main(String[] args) {
		
		Single_Fan_Thread fan_s1 = new Single_Fan_Thread().getInstance();//<1000번지 주소> 하나로 쓸 수 있다. static과 유사하게 사용한다.

		System.out.println("[LED 선풍기]");
		System.out.printf("선풍기를 켜시겠습니까? (Y/N) : ");
		fan_s1.fan_power();
		while(fan_s1.fan_power == true)
		{
			System.out.println("<선풍기 상태>");
			System.out.printf("LED색상 : %s, 풍속 : %d단, 회전각도 : %d도, 타이머 : %d초\n\n",fan_s1.led, fan_s1.dan, fan_s1.ang,  fan_s1.time);
			System.out.println("선풍기 기능을 설정합니다.");
			System.out.println("1.LED 색상변경 2.풍속설정 3.회전각도 4.타이머 설정 5.선풍기 끄기");
			int menu_sel = fan_s1.ac.nextInt();
			System.out.println();
			
			if(menu_sel == 1)
			{
				fan_s1.LED();//LED 색상변경
			}
			else if(menu_sel == 2)
			{
				fan_s1.speed();//풍속설정
			}
			else if(menu_sel == 3)
			{
				fan_s1.angle();//회전각도
			}
			else if(menu_sel == 4)
			{
				fan_s1.timer();//타이머 설정
			}
			else if(menu_sel == 5)
			{
				System.out.println("선풍기를 종료합니다.");
				break;
			}
			else
			{
				System.out.println("잘못입력하셨습니다. 다시 입력해주세요!\n");
			}

		}//while
	}//main
}//class Single_Fan_Thread

 

package Team3;

class Timer extends Thread//Single_Fan_Thread과 다른 스레드를 사용하기 위해 생성한 클래스
{
	Single_Fan_Thread sft = new Single_Fan_Thread().getInstance();//Single_Fan_Thread의 주소 알아오기
	
	int time_set = sft.time;//time_set을 Single_Fan_Thread의 time으로 설정한다.
	
	public int getTime_set()//time_set을 반환한다.
	{
		return time_set;
	}


	public void setTime_set(int time_set)//time_set을 설정한다. 
	{
		this.time_set = time_set;
	}
	
	public void run()//스레드 동작
	{
		try 
		{
			Thread.sleep(time_set*1000);//time_set초만큼 실행정지
			sft.fan_power = false;//전원을 false로 설정
			System.out.println("선풍기 종료");
			System.exit(0);//프로그램 종료
		} 
		catch (InterruptedException e) 
		{
			
		}
	}
}

 

실행결과는 다음과 같다. (나머지부분은 이전과 동일하여 타이머만 실행하였다.)

 

[LED 선풍기]
선풍기를 켜시겠습니까? (Y/N) : y
선풍기를 킬게요

<선풍기 상태>
LED 색상 : 빨강, 풍속 : 1단, 회전각도 : 90도, 타이머 : 0초

선풍기 기능을 설정합니다.
1.LED 색상변경 2. 풍속 설정 3. 회전각도 4. 타이머 설정 5. 선풍기 끄기
4

설정할 시간을 입력하세요. : 10
10초로 설정되었습니다.
<선풍기 상태>
LED색상 : 빨강, 풍속 : 1단, 회전각도 : 90도, 타이머 : 10초

선풍기 기능을 설정합니다.
1.LED 색상변경 2. 풍속 설정 3. 회전각도 4. 타이머 설정 5. 선풍기 끄기
선풍기 종료//10초후 종료된다.

 

스레드를 사용하면서 sleep과 인터럽트, 강제 종료 등을 추가적으로 공부하였다.