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

LWJGL创建窗口报GLFW仅可在主线程使用错误如何解决

报错原因

GLFW原生设计要求所有API调用必须在应用主线程执行,macOS平台限制更严格,要求必须在进程第一线程执行。你现在将GLFW初始化、窗口创建等操作放到了自定义的game子线程中执行,哪怕配置了-XstartOnFirstThread也会触发报错。

解决方法

方案1:调整线程架构(推荐,符合LWJGL最佳实践)

无需修改任何配置,仅调整代码结构即可,兼容性最好,不会出现未知崩溃问题:

  • GLFW初始化、窗口创建、渲染、事件处理等和GLFW相关的操作全部放在主线程执行
  • 纯游戏逻辑运算(如数值更新、物理计算等)放到独立子线程运行,避免阻塞渲染

调整后的参考代码如下:

Main.java

package main;

import engine.io.Window;
import org.lwjgl.glfw.GLFW;

public class Main {
    public static Window window;
    public static final int WIDTH = 1280, HEIGHT = 760;
    // 线程安全的运行标记位
    private static volatile boolean isRunning = true;

    public static void main(String[] args) {
        // 主线程执行GLFW相关初始化
        System.out.println("Initializing game!");
        window = new Window(WIDTH, HEIGHT, "game");
        window.create();

        // 启动独立线程处理纯游戏逻辑更新
        Thread gameUpdateThread = new Thread(() -> {
            while (isRunning) {
                update();
                // 可按需调整休眠时间控制更新频率
                try {
                    Thread.sleep(16);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "game");
        gameUpdateThread.start();

        // 主线程处理渲染和GLFW事件循环
        while (isRunning && !GLFW.glfwWindowShouldClose(window.getWindowHandle())) {
            render();
            // 必须在主线程调用GLFW事件轮询
            GLFW.glfwPollEvents();
        }
        isRunning = false;
    }

    private static void update() {
        System.out.println("Updating game");
    }

    private static void render() {
        System.out.println("Rendering game");
    }
}

Window.java 新增获取窗口句柄的方法(供外部调用GLFW方法使用)

在你的Window类中添加如下代码:

public long getWindowHandle() {
    return window;
}

如果你是macOS平台,调整架构后仍然需要保留-XstartOnFirstThread启动参数


方案2:关闭GLFW线程检查(仅临时调试用,不推荐生产环境使用)

如果暂时不想调整架构,可以通过配置关闭线程检查,有两种配置方式:

  1. 代码配置:在调用任何GLFW方法之前添加配置代码
    首先导入Configuration类:
import org.lwjgl.system.Configuration;

然后在main方法第一行添加:

Configuration.GLFW_CHECK_THREAD0.set(false);
  1. JVM参数配置:启动时添加如下参数
-Dorg.lwjgl.glfw.checkThread0=false

注意:macOS平台受系统本身的UI线程限制,就算关闭检查也大概率会出现运行崩溃,不建议使用该方案


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:36:03