DDIT_Advanced_Java <Thread> 경마프로그램(1)

Gyeomii·2022년 5월 24일
0

DDITAdvancedJava

목록 보기
5/6
post-thumbnail

🛑코드수정

경마프로그램(2) 작성예정

다시써야해서 매우 매우 귀찮고 화가난다.

📌Full Code

💾 [깃허브 Full Code]


📌HorseRacing Class

조건

  • 1번 ~ 10번 경주마가 경주를 한다.
  • 말은 Horse라는 이름의 클래스로 구성하고 말이름, 등수를 멤버변수로 갖는다.
  • 등수를 오름차순으로 정렬할 수 있는 기능을 클래스에 구현한다.(Comparable)
  • 경기 구간은 1~50구간으로 설정, 말의 위치는 > 로 나타낸다.

변수

  • rankCnt : 각 말의 등수 및 경주가 끝났는지 체크하기위한 static변수
  • end : while문을 끝내기 위한 변수
  • horse : Horse클래스 객체를 담기 위한 ArrayList

for문 별 해석

  • horse리스트에 Horse객체 10마리 담기 (ArrayList<Horse> horse)
		for (int i = 1; i <= 10; i++) {
			horse.add(new Horse(i + "번마"));
		}
  • racing 리스트에 RacingThread(name)객체를 담는다 (ArrayList<RacingThread> racing)
for (int i = 0; i < 10; i++) {
			// racing리스트.add(new RacingThread쓰레드(horse리스트.get(i번배열).getName()))
			racing.add(new RacingThread(horse.get(i).getName()));
		}
  1. name을 가져오기 위해 horse리스트에서 i번 배열을불러온다(= Horse객체)
    horse.get(i)	
  2. 불러온 Horse객체에 getName을 하여 이름을 불러온다.
    horse.get(i).getName()
  3. 이름을 RacingThread 객체에 담는다
    RacingThread(horse.get(i).getName())
  • 10개의 쓰레드를 실행시킨다 (racing.get(i) = i번에 담긴 RacingThread 객체)
for (int i = 0; i < racing.size(); i++) {
		 // racing.get(i)[= i번 쓰레드].start()
			racing.get(i).start();
		}
public class HorseRacing {
	static int rankCnt = 0;
	static boolean end = false;
	static ArrayList<Horse> horse = new ArrayList<>();

	public static void main(String[] args) {
		ArrayList<RacingThread> racing = new ArrayList<>();
		// horse리스트에 Horse객체 10마리 담기
		for (int i = 1; i <= 10; i++) {
			horse.add(new Horse(i + "번마"));
		}
		for (int i = 0; i < 10; i++) {
			// racing리스트.add(new RacingThread쓰레드(horse리스트.get(i번배열).getName()))
			racing.add(new RacingThread(horse.get(i).getName()));
		}

		for (int i = 0; i < racing.size(); i++) {
			// racing.get(i)[= i번 쓰레드].start()
			racing.get(i).start();
		}
		
		System.out.println("==========================[Bang]============================");

		while (!end) {
			for (RacingThread raceHorse : racing) { // Racing쓰레드가 담긴 racing리스트에서 
				try {                               // 쓰레드를 하나씩 꺼내서
					System.out.println(raceHorse); // 쓰레드 값 출력
					Thread.sleep(50); // 출력텀
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println();
			
		}

		Collections.sort(horse);// 순위정렬

		System.out.println("============================================================");
		System.out.println();
		System.out.println("[순위]");
		for (Horse h : horse) {
			System.out.println(h.getRank() + "등\t: " + h.getName());
		}
	}
}

📌RacingThread Class

변수

  • name : 말의 이름
  • ArrayList<String> section : 1~50구간을 리스트에 담는다.
  • randomTime : 무작위 난수 생성

생성자, 메소드

  • RacingThread(name) :
    객체생성시 반환된 name을 저장하고 addSection()으로 각 말의 구간을 저장.
  • addSection() : 콘솔에 출력될 말이 달리는 구간("-") 50개를 리스트에 저장.
    (section내용) [-------------------------------------------]
  • run() : implements 받은 Thread의 run()을 override한 메소드
  • toString() : 콘솔에 말이 달리는 구간을 출력할 때 형태를 지정하는 메소드
    '말이름 | ---------------------->------------------' 형태

run() 해석

  • for문
  1. RacingThread가 실행되면 for문이 총 50번 실행된다.
  2. i=0 일 때 if문을 지나 section.set(i,">");이 실행된다.
section리스트에는 "-"50개 저장되어있으므로
section.set(0,">")이 실행되면 0번의 "-"">"로 대체된다.
(section 내용) [>------------------------------------------]
  1. Thread.sleep(randomTime)이 실행된다.
Thread가 다음 for문을 실행하기까지 randomTime만큼 멈춘다.(i=0-> sleep-> i=1)
  1. i=1일 때 if문안에 section.set(i-1,"-");이 실행된다.
section.set(0,"-")이 실행되면 0번에 있는 ">""-"로 대체된다.
(section 내용) [-------------------------------------------]
if문을 나와 section.set(1,">");이 실행되면 1번의 "-"">"로 대체된다.
 (section 내용) [->-----------------------------------------]
  1. 반복
for (int i = 0; i < 50; i++) {
			if (i != 0) { // i번 리스트에 ">"이 있으면 i-1번 배열에 ----를 출력하는 for문
				section.set(i - 1, "-");// > 뒤에 "-"로 하나씩 대체해서
			} // ">"이 앞으로 한칸씩 가는것처럼 보이게 하기
			section.set(i, ">"); // i가 커질수록 ">"을 한칸 앞으로
			try {// sleep()난수 생성
				Thread.sleep(randomTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
  • rankCnt
  1. for문이 50번 실행되면 HorseRacing.rankCnt++;실행
가장 먼저 for문이 끝난 Thread가 1등이므로 static으로 선언된 rankCnt=0;이
rankCnt++로 인해 1이 저장된다.
  1. if(rankCnt값이 10과 같으면) {end=true}
  • 각 쓰레드의 for문이 종료될 때(경주가 끝남) rankCnt++이 실행되므로
    10마리 모두 경주가 끝나야 rankCnt 값이 10이 된다.
  • static으로 선언된 변수는 값이 프로그램 실행동안 사라지지 않고 계속 저장되어 있다.
    1. 1번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=1)
    2. 2번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=2)
      :
    3. 10번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=10)
  • rankCnt=10이므로 if문 실행 -> HorseRacing.end = true;
  • end=true가 되면 경기가 모두 종료된다.
HorseRacing.rankCnt++;
if (HorseRacing.rankCnt >= HorseRacing.horse.size()) { // 총 10마리 경주 완료시
		HorseRacing.end = true;
}
  1. 등수 저장
for (int i = 0; i < HorseRacing.horse.size(); i++) {
			if (HorseRacing.horse.get(i).getName().equals(name)) { // 경주가 종료된 말과 이름이 같은 horse객체에
				HorseRacing.horse.get(i).setRank(HorseRacing.rankCnt);// 등수 저장
			}
}
class RacingThread extends Thread {
	private String name;
	private ArrayList<String> section = new ArrayList<>(); // 구간 생성
	Random rnd = new Random();
	int randomTime = rnd.nextInt(50) + 200; // 난수 생성

	// 생성자
	public RacingThread(String name) {
		this.name = name;
		addSection();
	}

	public void addSection() {
		for (int i = 0; i < 50; i++) {
			section.add("-"); // 말이 달리는 구간 ------- 만들기
		}
	}

	@Override
	public void run() {
		for (int i = 0; i < 50; i++) {
			if (i != 0) { // i번 리스트에 ">"이 있으면 i-1번 배열에 ----를 출력하는 for문
				section.set(i - 1, "-");// > 뒤에 "-"로 하나씩 대체해서
			} // ">"이 앞으로 한칸씩 가는것처럼 보이게 하기
			section.set(i, ">"); // i가 커질수록 ">"을 한칸 앞으로

			try {// sleep()난수 생성
				Thread.sleep(randomTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// static으로 선언된 rankCnt에 RacingHorse쓰레드가 종료된 순서대로 rankCnt++
		HorseRacing.rankCnt++;
		if (HorseRacing.rankCnt >= HorseRacing.horse.size()) { // 총 10마리 경주 완료시
			HorseRacing.end = true;
		}

		for (int i = 0; i < HorseRacing.horse.size(); i++) {
			if (HorseRacing.horse.get(i).getName().equals(name)) { // 경주가 종료된 말과 이름이 같은 horse객체에
				HorseRacing.horse.get(i).setRank(HorseRacing.rankCnt);// 등수 저장
			}
		}
	}

	@Override
	public String toString() {
		String str = "";
		for (int i = 0; i < section.size(); i++) {
			str += section.get(i); // str에 for문 으로 만든 section을 담고
		}
		return name + "\t| " + str; // '이름 | ----------->-------------------- ' 형태로 출력
	}
}

📌Horse Class

//Horse 클래스
class Horse implements Comparable<Horse> {
	private String name; // 말 이름
	private int rank; // 등수

	public Horse(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getRank() {
		return rank;
	}

	public void setRank(int rank) {
		this.rank = rank;
	}

	// 등수(rank)의 오름차순으로 정렬
	@Override
	public int compareTo(Horse horse) {
		return Integer.compare(getRank(), horse.getRank());
	}
}
profile
김성겸

0개의 댓글