Java多线程暂停

标签 java multithreading

My Goal

我是java中多线程的新手,我正在尝试创建pong。我只会在此处包含一些与问题相关的代码。

Problem

我希望能够通过按空格键暂停游戏,然后通过按空格键再次恢复游戏。以下代码可以暂停游戏,但无法恢复。以后所有的按键都不会被识别。看起来好像主线程正在暂停。

Code

主类

public class MainManager {

    private Ticker ticker;
    private Thread tickerThread;

    private boolean active;

    public MainManager() {
        ticker = new Ticker(this,10);
        tickerThread = new Thread(ticker);

        tickerThread.start();
    }

    public synchronized void tick() {
        // Does necesary things for each game tick
    }

    public void toggleState() {
        if (this.active) {
            ticker.pause();
        } else {
            this.setActive(true);
            notify();
        }
    }

    public void setActive(boolean b) {
        this.active = b;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
                    @Override
                   public void run() {
                        MainManager manager = new MainManager();
                   }
        });
    }
}

股票代码类

public class Ticker implements Runnable {

    private MainManager manager;
    private int tick;

    public Ticker(MainManager manager,int tick) {
        this.manager = manager;
        this.tick = tick;
    }

    @Override
    public void run() {
        manager.setActive(true);
        while (true) {
            try {
                Thread.sleep(this.tick);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            manager.tick();
        }
    }

    public void setTickSpeed(int speed) {
        this.tick = speed;
    }   

    public synchronized void pause() {
        synchronized(manager) {
            try {
                System.out.println("Waiting for Manager");
                manager.setActive(false);
                manager.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

KeyListener 类

注意: 此类被添加到在 MainManager 构造函数内部构造的 JFrame 中。如果这个 JFrame 类对我的问题很重要,我将发布代码,请告诉我

public class KeyboardListener implements KeyListener {

    private MainManager manager;

    public KeyboardListener(MainManager manager) {
        this.manager = manager;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("KeyPressed);
        //This line only prints on the first spacebar. 
        //After the game is paused, it never prints again.  Despite me spamming spacebar
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            manager.toggleState();
        }
    }
}

如何通过按键让 tickerThread 暂停和恢复?有其他批评欢迎指正。

最佳答案

您从未离开过 Swing 事件调度线程。

您的股票在另一个线程中愉快地滴答作响,工作正常。但是,如果我们遵循您的切换调用的路径,它永远不会到达另一个线程。

你的空格键被按下->Swing EDT巫术->keyPressed->manager.toggleState()->ticker.pause() 现在我们与Manager同步,这并不难。我们仍然在主线程上!然后我们等待。

您的空格键被按下 ->Swing EDT 已暂停。在另一个线程中运行的代码的唯一部分是 run 方法。

您希望在 EDT 之外运行与游戏逻辑相关的所有内容。在与 JFrame 和事件处理程序不同的线程中运行 MainManager 和 Ticker,并同步或使用锁定的 boolean 值将数据从 IO 线程发送到逻辑线程。

关于Java多线程暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30603740/

相关文章:

Java PDF 操作,基于模式匹配替换文本,带有超链接

java - Tarjan 的算法错误地检测周期

java - 为什么 AbstractTableModel 上的 fireTableChanged() 从最后到第一个通知监听器?

java - 通过处理程序消息以最少的分配传递数组的副本?

java - 检查对象的过期日期以在后台删除

multithreading - 为什么基于 channel 的 Lock block ?

java - "EEE MMM dd HH:mm:ss ZZZ yyyy"日期格式转换为java.sql.Date

java - 服务器重启后 Liferay Scheduler 不工作

multithreading - 多线程分析技术

java - 我可以在 Scala 中将本地 var 作为 Volatile,因为在 Java 中这是不可能的吗?