来自JFrame#keyPressed()的Thread#run()和Thread#notify()中的Thread#wait()-我的实现线程安全吗?

时间:2018-09-13 11:20:42

标签: java thread-safety keylistener

很抱歉,如果我发布的内容包含编译错误,目前我还没有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();

    }

}

您可以用诸如确定AI动作之类的动作替换sysout("Doing stuff!"),然后再选择玩家按下AI的键,然后在玩家+ AI选择他们的动作后,相互使用并完成所有回合操作。

我还必须说一个事实,即我将同时具有1..1 Frame对象和0..1 Battle对象处于活动状态。

所以。我对自己写的东西有很多疑问。

问题1:由于我是Threads的新手,所以我想先知道我的keyPressed的条件是否写得很好(我我不确定我是否了解Thread.State.WAITINGThread.State.BLOCKED之间的区别) 更一般地说,我的代码将始终执行相同的操作,并且确实有效吗?我认为的方式(通过输入)

问题2:出于好奇,在Frame的构造函数中,如果我颠倒battle = new Battle();addKeyListener(this);,然后将keyPressed的条件更改为battle != null && battle.getState() == Thread.State.WAITING如果我在执行battle = new Battle()之前按了足够快的键来触发事件?

非常感谢您!

编辑:仍在寻求帮助。 :)我也在Eclipse上对其进行了测试,并且似乎正常运行。

0 个答案:

没有答案