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

LibGDX中额外线程导致FPS下降的问题求助

问题分析与解决方案

你的问题核心有两个:

  • 每帧在render()里创建新线程+调用join():线程创建销毁的开销极大,而且join()会阻塞主线程(渲染线程),直接导致FPS暴跌,这是掉帧的根本原因。
  • 把线程放构造函数后,线程跑完一次while循环就终止了:Thread对象只能start()一次,终止后无法重启,所以你调用restart()只是重置了m,但线程已经停止工作,自然增量固定。

方案一:完全不用线程(推荐)

你的需求是右键长按增加质量,逻辑非常轻量,完全没必要开线程。直接利用render()每帧执行的特性,结合时间间隔控制增量即可,性能拉满还无线程问题:

步骤1:在Screen类中添加状态变量

private boolean isRightButtonHeld = false;
private long lastMassIncrementTime = 0;
private static final long INCREMENT_INTERVAL = 50; // 每50ms加一次质量,可调整速度

步骤2:在render()中处理输入与增量逻辑

@Override
public void render(float delta) {
    // 处理右键按下事件:重置质量,标记长按状态
    if (Gdx.input.isButtonJustPressed(Input.Buttons.RIGHT)) {
        isRightButtonHeld = true;
        MainScreen.m = 100000;
        lastMassIncrementTime = System.currentTimeMillis();
    } 
    // 处理右键松开事件:创建行星,取消长按状态
    else if (Gdx.input.isButtonJustReleased(Input.Buttons.RIGHT)) {
        isRightButtonHeld = false;
        planets.add(new Planet(10, MainScreen.m, mouseOnWorld2.x, mouseOnWorld2.y));
    }

    // 长按期间按固定间隔增量
    if (isRightButtonHeld) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastMassIncrementTime >= INCREMENT_INTERVAL) {
            MainScreen.m += 100;
            System.out.println(MainScreen.m);
            lastMassIncrementTime = currentTime;
        }
    }

    // 你的其他渲染逻辑...
}

方案二:如果一定要用线程(正确写法)

如果坚持要用线程,必须用单个持久线程,通过标志位控制工作状态,避免重复创建线程,同时解决线程安全与空循环问题:

步骤1:改造IncrementMass线程

public class IncrementMass extends Thread {
    // volatile保证多线程下状态可见性
    private volatile boolean running = false;
    private volatile boolean needReset = false;
    private static final long SLEEP_MS = 50; // 休眠避免空循环占用CPU

    @Override
    public void run() {
        while (!isInterrupted()) {
            synchronized (this) {
                // 未激活时等待通知,避免空跑
                while (!running) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        // 线程被中断,直接退出
                        return;
                    }
                }
                // 重置质量
                if (needReset) {
                    MainScreen.m = 100000;
                    needReset = false;
                }
            }

            // 右键按住时增量
            if (Gdx.input.isButtonPressed(Input.Buttons.RIGHT)) {
                // 同步共享变量读写,避免线程安全问题
                synchronized (IncrementMass.class) {
                    MainScreen.m += 100;
                    System.out.println(MainScreen.m);
                }
                try {
                    Thread.sleep(SLEEP_MS);
                } catch (InterruptedException e) {
                    return;
                }
            } else {
                // 松开右键,停止工作
                synchronized (this) {
                    running = false;
                }
            }
        }
    }

    // 启动增量(右键按下时调用)
    public synchronized void startIncrement() {
        needReset = true;
        running = true;
        notify(); // 唤醒等待的线程
    }

    // 停止增量(右键松开时调用)
    public synchronized void stopIncrement() {
        running = false;
    }
}

步骤2:在Screen中使用线程

private IncrementMass incrementMass;

// 在Screen构造函数中初始化线程(仅执行一次)
public MainScreen() {
    incrementMass = new IncrementMass();
    incrementMass.setDaemon(true); // 设置为守护线程,程序退出时自动销毁
    incrementMass.start();
}

@Override
public void render(float delta) {
    // 处理右键按下
    if (Gdx.input.isButtonJustPressed(Input.Buttons.RIGHT)) {
        incrementMass.startIncrement();
    } 
    // 处理右键松开
    else if (Gdx.input.isButtonJustReleased(Input.Buttons.RIGHT)) {
        incrementMass.stopIncrement();
        // 同步获取最新质量值
        long currentMass;
        synchronized (IncrementMass.class) {
            currentMass = MainScreen.m;
        }
        planets.add(new Planet(10, currentMass, mouseOnWorld2.x, mouseOnWorld2.y));
    }

    // 你的其他渲染逻辑...
}

// 屏幕销毁时中断线程
@Override
public void dispose() {
    incrementMass.interrupt();
}

内容的提问来源于stack exchange,提问作者eisa.exe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 03:54:15