Java & Spring Boot

[Java] 멀티스레딩 연습 - 금고, 해커, 경찰 게임 구현

Accept 2024. 11. 24. 21:25

프로그램 개요

이 프로그램은 다음과 같은 역할을 가진 세개의 스레드로 구성됩니다.

 

 

구성

1. 금고 (Vault)

  • 임의의 비밀번호를 가지고 있으며, 해커가 추측한 비밀번호를 검증

2. 해커 스레드 (HackerThread)

  • 금고의 비밀번호를 추측하는 스레드
  • 오름차순(AscendingHackerThread)과 내림차순(DescendingHackerThread)으로 비밀번호를 추측.

3. 경찰 스레드 (PoliceThread)

  • 해커를 막으려는 역할
  • 10초 동안 카운트다운을 하며, 시간이 다 되면 프로그램 종료

 

실행 흐름

1. Vault 객체 생성

  • 임의의 비밀번호를 가진 금고 생성

2. 해커 및 경찰 스레드 생성

  • 오름차순 해커(AscendingHackerThread), 내림차순 해커(DescendingHackerThread), 경찰(PoliceThread) 스레드를 생성

3. 스레드 시작

  • 모든 스레드를 병렬로 실행
  • 해커는 금고 비밀번호를 추측하며, 경찰은 10초 동안 카운트다운

4. 프로그램 종료 조건

  • 해커가 비밀번호를 맞추면 프로그램 종료
  • 경찰이 카운트다운을 완료하면 프로그램 종료

 

package thread.example.creation;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Threads Creation - Thread Inheritance
 */
public class ThreadInheritance {

    public static final int MAX_PASSWORD = 9999;

    public static void main(String[] args) {
        Random random = new Random();

        Vault vault = new Vault(random.nextInt(MAX_PASSWORD));

        List<Thread> threads = new ArrayList<>();

        threads.add(new AscendingHackerThread(vault));
        threads.add(new DescendingHackerThread(vault));
        threads.add(new PoliceThread());

        for (Thread thread : threads) {
            thread.start();
        }
    }

    private static class Vault {
        private int password;

        public Vault(int password) {
            this.password = password;
        }

        public boolean isCorrectPassword(int guess) {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
            }
            return this.password == guess;
        }
    }

    private static abstract class HackerThread extends Thread {
        protected Vault vault;

        public HackerThread(Vault vault) {
            this.vault = vault;
            this.setName(this.getClass().getSimpleName());
            this.setPriority(Thread.MAX_PRIORITY);
        }

        @Override
        public void start() {
            System.out.println("Starting thread " + this.getName());
            super.start();
        }
    }

    private static class AscendingHackerThread extends HackerThread {

        public AscendingHackerThread(Vault vault) {
            super(vault);
        }

        @Override
        public void run() {
            for (int guess = 0; guess < MAX_PASSWORD; guess++) {
                if (vault.isCorrectPassword(guess)) {
                    System.out.println(this.getName() + " guessed the password " + guess);
                    System.exit(0);
                }
            }
        }
    }

    private static class DescendingHackerThread extends HackerThread {

        public DescendingHackerThread(Vault vault) {
            super(vault);
        }

        @Override
        public void run() {
            for (int guess = MAX_PASSWORD; guess >= 0; guess--) {
                if (vault.isCorrectPassword(guess)) {
                    System.out.println(this.getName() + " guessed the password " + guess);
                    System.exit(0);
                }
            }
        }
    }

    private static class PoliceThread extends Thread {
        @Override
        public void run() {
            for (int i = 10; i > 0; i--) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                System.out.println(i + " second before the police arrive");
            }

            System.out.println("Game over for you hackers");
            System.exit(0);
        }
    }
}