You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java游戏开发:启动线程后Run方法未执行问题排查

问题诊断与修复方案

嘿,我一眼就揪出了导致run()方法没被调用的关键问题——你的Game类构造函数提前把running设为true了,这直接让Launcher的start()方法跳过了线程创建和启动的核心逻辑!

问题根源拆解

咱们捋一遍你的执行流程:

  1. Launcher的main方法里先创建Game game = new Game();,在Game的构造函数中,你直接执行了this.running = true;
  2. 接着调用obj.start(),进入start方法后首先判断if(game.running) return;——此时running已经是true了,所以方法直接返回,根本没执行thread = new Thread(game); thread.start();这两行关键代码!

修复步骤

1. 移除Game构造函数中提前设置running的代码

把Game构造函数里的this.running = true;删掉,让running保持默认的false(布尔类型成员变量默认值就是false,你也可以显式写public boolean running = false;让代码更清晰)。

2. 优化:给running添加volatile修饰(可选但强烈推荐)

因为running是多线程共享的变量,为了保证线程间的状态可见性,避免线程缓存导致的逻辑异常,建议用volatile修饰这个变量。

修改后的代码示例

修改后的Game类(关键部分)

public class Game extends JFrame implements Runnable{
    // 添加volatile修饰符,保证多线程状态可见性
    public volatile boolean running = false;
    private static int WIDTH = 1280 , HEIGHT = 720;
    private Screen screen;

    public Game() {
        this.setTitle("Game");
        this.setSize(WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        // 删掉这行提前设置running的代码:this.running = true;
        this.setVisible(true);
        init();
    }

    // 其余方法保持不变...
}

修改后的Launcher类(无需改动,确认逻辑)

public class Launcher {
    private Thread thread;
    private static Game game;

    public static void main(String[] args) {
        Launcher obj = new Launcher();
        game = new Game();
        obj.start();
    }

    public synchronized void start() {
        if(game.running) return;
        game.running = true;
        thread = new Thread(game);
        thread.start(); // 现在这行代码会正常执行了!
    }

    // stop方法保持不变...
}

额外小提醒

另外,Swing组件相关的操作(比如setVisible(true)、添加组件)最好放在事件调度线程(EDT)中执行,避免UI线程冲突问题,你可以用SwingUtilities.invokeLater()包装这些代码,比如在Game构造函数里:

SwingUtilities.invokeLater(() -> {
    this.setTitle("Game");
    this.setSize(WIDTH, HEIGHT);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
    init();
});

这样修改后,你的run()方法应该就能正常被调用,控制台会打印出"called"了!

内容的提问来源于stack exchange,提问作者Saumi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:17:46