관리 메뉴

거니의 velog

230831_스레드 3 본문

대덕인재개발원_자바기반 애플리케이션

230831_스레드 3

Unlimited00 2023. 8. 31. 13:48

[RockPaperScissor.java]

package kr.or.ddit.basic;

import javax.swing.JOptionPane;

/*
 * 컴퓨터와 가위 바위 보를 진행하는 프로그램을 작성하시오.
 * 
 * 컴퓨터의 가위 바위 보는 난수를 이용하여 정하고,
 * 사용자의 가위 바위 보는 showInputDialog() 메서드를 이용하여 입력 받는다.
 * 
 * 입력 시간은 5초로 제한하고 카운트 다운을 진행한다.
 * 5초 안에 입력이 없으면 게임에 진 것으로 처리하고 프로그램을 종료한다.
 * 
 * 5초 안에 입력이 있으면 승패를 구해서 결과를 출력한다.
 * 
 * 결과예시)
 * 1) 5초 안에 입력을 못했을 경우
 * 		-- 결 과 --
 * 시간 초과로 당신이 졌습니다...
 * 
 * 2) 5초 안에 입력했을 경우
 * 		-- 결 과 --
 * 		컴퓨터 : 가위
 * 		당  신 : 바위
 * 		결  과 : 당신이 이겼습니다.
 * 
 */

public class RockPaperScissor {

	public static boolean inputCheck;
	
	public static void main(String[] args) {
		
		GameCountDown gcd = new GameCountDown();
		
		// 난수를 이용하여 컴퓨터의 가위 바위 보 정하기
		String[] data = {"가위", "바위", "보"};
		int idx = (int)(Math.random() * 3); // 0부터 2 사이의 난수 만들기
//		System.out.println(idx);
		String com = data[idx]; // 컴퓨터의 가위 바위 보를 정한다.
//		System.out.println(com);
		
		// 사용자로부터 가위 바위 보 입력 받기
		gcd.start(); // 카운트다운 쓰레드 작동 시작...
		
		String man = null;
		do {
			man = JOptionPane.showInputDialog("가위, 바위, 보를 입력하세요...");
//		}while(!("가위".equals(man) || "바위".equals(man) || "보".equals(man))); // null값 체크, 가위-바위-보만 입력하도록 처리
		}while(!"가위".equals(man) && !"바위".equals(man) && !"보".equals(man)); // 드모르간 법칙
		
		inputCheck = true;
		
		// 결과 판정하기
		String result = "";
		
		if(man.equals(com)) {
			result = "비겼습니다.";
		}else if( (man.equals("가위") && com.equals("보")) || 
				  (man.equals("바위") && com.equals("가위")) || 
				  (man.equals("보") && com.equals("바위")) ) {
			result = "당신이 이겼습니다.";
		}else {
			result = "당신이 졌습니다.";
		}
		
		// 결과 출력
		System.out.println("-- 결 과 --");
		System.out.println("컴퓨터 : " + com);
		System.out.println("사용자 : " + man);
		System.out.println("결과 : " + result);
		System.exit(0);
		
	}

}

// 카운트다운 스레드
class GameCountDown extends Thread {
	
	@Override
	public void run() {
		System.out.println("카운트 시작!");
		
		for(int i=5; i>0; i--) {
			if(RockPaperScissor.inputCheck) {
				return;
			}
			System.out.println(i + "초 남았습니다...");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		
		System.out.println("-- 결 과 --");
		System.out.println("시간 초과로 당신이 졌습니다.");
		System.exit(0);
	}
	
}

 



[ThreadTest08.java]

package kr.or.ddit.basic;

// 데몬 스레드 연습 ==> 자동 저장하는 기능

public class ThreadTest08 {

	public static void main(String[] args) {
		
		AutoSaveThread autoSave = new AutoSaveThread();
		
		autoSave.setDaemon(true); // 데몬 쓰레드로 설정하기 (반드시 start() 메서드 호출 전에 설정해야 한다.)
		autoSave.start();
		
		try {
			for(int i=1; i<=20; i++) {
				System.out.println(i+"초");
				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		System.out.println("main 쓰레드 종료...");
		
	}

}

// 자동 저장하는 쓰레드 ==> 3초에 한번씩 자동 저장하는 쓰레드
class AutoSaveThread extends Thread {
	// 작업 내용을 저장하는 메서드
	private void save() {
		System.out.println("작업한 내용을 저장합니다...");
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
			save();
		}
	}
}



[ThreadTest09.java]

package kr.or.ddit.basic;

// 쓰레드의 상태를 확인하는 예제

public class ThreadTest09 {

	public static void main(String[] args) {
		
		StatePrintThread th = new StatePrintThread(new TargetThread());
		th.start();
		
	}
	
}

// 쓰레드 상태의 검사 대상이 되는 쓰레드
class TargetThread extends Thread {
	@Override
	public void run() {
		
		long a = 0;
		
		for(long i=1L; i<20_000_000_000L; i++) {
			a += i;
		}
		
		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		for(long i=1L; i<20_000_000_000L; i++) {
			a += i;
		}
		
	}
}

// 위의 TargetThread의 상태를 출력하는 쓰레드
class StatePrintThread extends Thread {
	private TargetThread target;
	
	// 생성자
	public StatePrintThread(TargetThread target) {
		this.target = target;
	}

	@Override
	public void run() {
		while(true) {
			// TargetThread 쓰레드의 상태값 구하기
			Thread.State state = target.getState();
			System.out.println("TargetThread의 상태값 => " + state);
			
			if(state == Thread.State.NEW) { // 쓰레드의 상태가 NEW 상태이면...
				target.start();
			}
			
			if(state == Thread.State.TERMINATED) { // 쓰레드의 상태가 TERMINATED(종료) 상태이면...
				break;
			}
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
			
		}
	}
}


[ThreadTest10.java]

package kr.or.ddit.basic;

// yield() 메서드 연습
public class ThreadTest10 {

	public static void main(String[] args) {
		
		YieldTestThread th1 = new YieldTestThread("1번 쓰레드");
		YieldTestThread th2 = new YieldTestThread("2번 쓰레드");
		
		th1.start();
		th2.start();
		
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		System.out.println("***************** 11111111111111111");
		
		th1.work = false;
		
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		System.out.println("***************** 22222222222222222");
		
		th1.work = true;
		
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		System.out.println("***************** 33333333333333333");
		
		th1.stop = true;
		th2.stop = true;
		
	}

}

// yield() 메서드 연습용 쓰레드
class YieldTestThread extends Thread {
	public boolean stop = false;
	public boolean work = true;
	
	// 생성자
	public YieldTestThread(String name) {
		super(name); // 쓰레드의 이름을 설정한다.
	}

	@Override
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println(getName() + " 작업중 ...");
			}else {
				System.out.println(getName() + " 양보...");
				Thread.yield(); // 계속 순서를 양보한다.
			}
		}
	}
}


[ThreadTest11.java]

package kr.or.ddit.basic;

// 3개의 쓰레드가 각각 알파벳을 A~Z까지 출력하는데
// 출력을 끝낸 순서대로 결과를 나타내는 프로그램 작성하기...

public class ThreadTest11 {

	public static void main(String[] args) {
		
		DisplayCharacter[] dcArr = new DisplayCharacter[] {
			new DisplayCharacter("홍길동"),
			new DisplayCharacter("이순신"),
			new DisplayCharacter("강감찬")
		};
		
		for(DisplayCharacter dc : dcArr) {
			dc.start();
		}
		
		for(DisplayCharacter dc : dcArr) {
			try {
				dc.join();
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		
		System.out.println();
		System.out.println("경기 결과 >> ");
		System.out.println("순 위 : " + DisplayCharacter.ranking);
		
	}

}

// A ~ Z까지 출력하는 쓰레드
class DisplayCharacter extends Thread {
	
	public static String ranking = "";
	private String name;
	
	// 생성자
	public DisplayCharacter(String name) {
		this.name = name;
	}

	@Override
	public void run() {
		for(char c='A'; c<='Z'; c++) {
			System.out.println(name + "의 출력 문자 ==> " + c);
			try {
				// 0 ~ 499 사이의 난수를 이용하여 일시 정지 시킨다.
				Thread.sleep( (int)(Math.random() * 500) );
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		System.out.println(name + "출력 끝...");
		
		// 출력을 끝낸 순서대로 이름을 배치한다.
		ranking += name + " ";
	}
	
}


[ThreadTest12.java]

package kr.or.ddit.basic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/*
10마리의 말들이 경주하는 프로그램을 작성하시오.

말은 Horse라는 이름의 쓰레드 클래스로 작성하는데 이 클래스는 말이름(String), 등수(int), 현재위치(int)를 
멤버변수로 갖는다. 그리고 이 클래스에는 등수를 오름차순으로 정렬할 수 있는 내부 정렬 기준이 있다. 
(Comparable 인터페이스 구현)

조건)

1) 경기 구간은 1 ~ 50구간으로 되어 있다.
2) 경기가 끝나면 등수 순으로 출력한다.
3) 경기 중에는 중간 중간에 각 말들의 위치를 아래와 같이 나타내 준다.

예시)
01번말 : --->-----------------------------------
02번말 : ------->-------------------------------
...
10번말 : ----->---------------------------------

*/

public class ThreadTest12 {

	public static void main(String[] args) {
		
		List<Horse> horses = new ArrayList<Horse>(); // 정렬을 해주기 위한 리스트
		for(int i=1; i<=10; i++) {
			int intLength = (int)(Math.log10(i)+1);
			String horseNum = "";
			if(intLength == 1) {
				horseNum = "0" + i;
			}else {
				horseNum = String.valueOf(i);
			}
			horses.add(new Horse(horseNum+"번 말"));
		}
//		System.out.println(horses);
		
		for(Horse hs : horses) {
			hs.start();
		}
		
		while(true) { // 현재 달리는 위치
			for(int i=0; i<horses.size(); i++) { // 말 10마리 만큼 반복
				System.out.print(horses.get(i).name + " : ");
				for(int j=1; j<=50; j++) {
					if(horses.get(i).place == j) { // i번째 말이 j칸 까지 도착하면
						System.out.print(">"); // >로 변환
						continue; // > 변환 후 첫 번째 for문으로 돌아가서 계속 반복
					}
					System.out.print("-"); // -을 출력
				}
				System.out.println();
			}
			
			try {
				Thread.sleep(500); // 0.5초 텀 두기.
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
			
			int endPoint = 0; // 말이 끝까지 도달한 포인트
			for(int k=0; k<horses.size(); k++) {
				if(horses.get(k).getState() == Thread.State.TERMINATED) { // 말이 끝까지 달렸다면
					endPoint++; // 도달한 말의 숫자를 증가시킴.
				}
			}
			
			if(endPoint == 10) { // 10번째 말까지 모두 달렸다면 반복문 종료
				break;
			}
			
			System.out.println("\n==========================================");
			// 끝나지 않으면 출력
		}
		
		System.out.println();
		Collections.sort(horses);
		System.out.println("===경기결과===");
		for(Horse h : horses) {
			System.out.println(h); // 도착한 순서대로 말 출력
		}
		
	}

}

class Horse extends Thread implements Comparable<Horse> {

	public static int setRank = 1;
	public String name;
	public int rank;
	public int place = 1;
	
	// 생성자
	public Horse(String name) {
		this.name = name;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 50; i++) {
			//System.out.println(name + "의 위치 : " + place);
			try {
				Thread.sleep((int) (Math.random() * 500));
			} catch (InterruptedException e) {
			
			}
			if(place < 50) { // 장소가 50까지 가야 된다. 즉, 50보다 작을 때 
				place++; // 증가
			}
		}
		System.out.println(name + "경기 완료");
		rank = setRank++; // 1등한 다음에 등수에 넣어줌
		System.out.println("등수는 " + rank);
	}

	@Override
	public int compareTo(Horse h) {
		return Integer.compare(rank, h.rank); // 비교해서 정렬;
	}

	@Override
	public String toString() {
		return name + " : " + rank + "등 ";
	}
	
}

'대덕인재개발원_자바기반 애플리케이션' 카테고리의 다른 글

230904_스레드 5  (0) 2023.09.04
230901_스레드 4  (0) 2023.09.01
230830_스레드 2  (0) 2023.08.29
230829_스레드 1  (0) 2023.08.29
230829_컬렉션 프레임워크 6  (1) 2023.08.29