Поток # wait () в Thread # run () и Thread # notify () из JFrame # keyPressed () - безопасна ли моя реализация Thread? - PullRequest
0 голосов
/ 13 сентября 2018

Извините, если то, что я публикую, содержит ошибки компиляции, у меня на данный момент нет компилятора IDE x, поэтому предположим, что у нас есть два класса: Battle, расширяющий Thread, и Frame, расширяющий JFrame и реализующий KeyListener, плюс Main. чтобы проверить их.

Battle.java:

public class Battle extends Thread{

    public synchronized void produce(){

        try{
            wait();
        }catch(InterruptedException e){}

    }

    public synchronized void consume(){

        notify();

    }

    @Override
    public void run(){

        int turn = 0;
        while(true){ //Just for testing
            System.out.println("[BATTLE]: Starting turn " + turn + "!");
            System.out.println("[BATTLE]: Doing stuff!");
            System.out.println("[BATTLE]: Waiting for user to press a key...");
            produce();
            System.out.println("[BATTLE]: Doing stuff!");
            System.out.println("[BATTLE]: Ending turn " + turn + "!");
            turn++;
        }

    }

}

Frame.java:

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class Frame extends JFrame implements KeyListener{

    private Battle battle;

    public Frame(){

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setTitle("Threads");
        setLocationRelativeTo(null);

        battle = new Battle();
        addKeyListener(this);
        setVisible(true);
        battle.start();

    }

    @Override
    public void keyPressed(KeyEvent e){

        if(battle.getState() == Thread.State.WAITING){
            System.out.println("[LISTENER]: Key <" + e.getKeyChar() + "> pressed.");
            System.out.println("[LISTENER]: Going back to battle execution.");
            battle.consume();
        }

    }

    @Override
    public void keyReleased(KeyEvent e){}

    @Override
    public void keyTyped(KeyEvent e){}

}

Main.java:

public class Main{

    public static void main(String[] args){

        new Frame();

    }

}

Вы можете заменить оба sysout("Doing stuff!") такими действиями, как определение действия ИИ, прежде чем выбрать свое, нажав клавишу, и после того, как игрок + ИИ выберет свое действие, использовать его друг против друга и делать все в конце хода.

Кроме того, я должен сказать, что я точно знаю, что у меня когда-нибудь будут активны объект 1..1 Frame и объект 0..1 Battle одновременно.

Итак. У меня есть куча вопросов о том, что я написал.

Вопрос 1: Поскольку я очень новичок в Threads в целом, и Я хотел бы сначала узнать, хорошо ли написано условие моего keyPressed или нет (я не уверен Я понял разницу между Thread.State.WAITING и Thread.State.BLOCKED) ? В целом, будет ли мой код всегда делать то же самое, и действительно ли он работает так, как я думаю (через вход) ?

Вопрос2: просто из любопытства, в конструкторе Фрейма, , если я поменяю battle = new Battle(); и addKeyListener(this);, я должен затем изменить свое состояние keyPressed на battle != null && battle.getState() == Thread.State.WAITING, если я нажму клавишу достаточно быстро запустить событие до выполнения battle = new Battle()?

Большое спасибо!

РЕДАКТИРОВАТЬ: Все еще просят помощи. :) Также я протестировал его на Eclipse, и он , казалось, работал просто отлично.

...