Как полностью остановить выполнение потока - PullRequest
0 голосов
/ 06 декабря 2018

Я искал StackOverflow, но не смог найти ответ на свой вопрос.

У меня есть класс Main: -

public class Main {
    public static Thread game = new Thread(new Start());
    public static void main(String[] args) {
        game.start();
        try {
            game.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

И у меня есть ветка игры (начальный класс): -

public class Start implements Runnable {
    private Timer timer = new Timer();
    private Thread timerThread = new Thread(timer, "timer");
    @Override
    public void run() {
        ...
        try {
            play();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
    public void play() throws IOException {
        ...
        timerThread.run();
        System.out.print("Enter a letter: ");
        char input = sc.next().toUpperCase().charAt(0);
        ...
        if(isPlaying) play();
    }
}

И у меня есть класс Timer: -

public class Timer implements Runnable {

    @Override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            try {
                System.out.println(i);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Main.game.interrupt();
    }
}

Теперь возникает проблема, что, когда я запускаю игру, таймер также запускается.Но по истечении 15 секунд нить таймера останавливается.Но выполнение программы не прекратилось.

Через 15 секунд компилятор все еще готов принять ввод.После ввода программа останавливается.

Я хочу немедленно принудительно остановить поток.Вскоре через 15 секунд я хочу остановить выполнение игрового потока в этот самый момент.

Я просмотрел некоторые учебники по многопоточности на Youtube и некоторые ранее заданные вопросы в StackOverflow, но мне не удалось найти решение.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Получаете ли вы NullPointerException?

Я проверил ваше решение, и вот что я получил.В этом случае ваша проблема заключается в том, что вы пытаетесь инициализировать поле game в Timer до инициализации статического свойства в классе Main.

Ради вашего понимания позвольте мнеперефразируя это: Когда ваш код запускает

private Thread game = Main.game;

, в Main.game ничего нет, и это потому, что Main.game будет инициализирован после инициализации экземпляров Start и Timer.

Самый простой способ решить эту проблему - удалить свойство private Thread game вашего таймера и просто вызвать Main.game.interrupt();

Edit 01: Как только вы решите первое, вам нужнопонять, как работает прерывание потока.Когда вы звоните Main.game.interrupt();, вы немедленно остановите его, только если поток спит.Если это так, поток выдаст InterruptedException, но это не то, что мы хотим, и я бы не рекомендовал это.В обычном потоке выполнение метода .interrupt() установит состояние целевого потока как «Прервано», но это только флаг boolean, который ничего не меняет (пока).Что вам нужно сделать, это проверить состояние этого флага в вашем методе рекурсии, чтобы, когда значение флага «прерывание» было равно true, вы изменили значение isPlaying на false.И вот как ваш поток остановится.

В коде это будет примерно так:

public void play() throws IOException {
        ...
        timerThread.run();
        System.out.print("Enter a letter: ");
        char input = sc.next().toUpperCase().charAt(0);
        if (Thread.interrupted()) {
            System.out.println("I should interrupt myself! ;)");
            isPlaying = false;
        }
        ...
        if(isPlaying) play();
}

Надеюсь, это поможет:)

0 голосов
/ 06 декабря 2018

Я думаю, что использование Thread.interrupt () - вполне приемлемый способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...