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

Java循环遇SIGINT中断,JavaFX数独求解器界面无响应求助

解决JavaFX数独求解器展示过程中的UI卡死与SIGINT中断问题

嗨,我一眼就看出问题所在了——你把JavaFX的UI线程给堵死啦!这也是为啥窗口会无响应,最后还收到SIGINT中断信号的原因。

问题根源

JavaFX的所有UI操作都必须在**JavaFX Application Thread(UI线程)**上执行,但你的loop方法里的while循环会死死占用这个线程,让它根本没法处理窗口重绘、用户输入这些必要的事件。系统一看程序僵住了,就会发送SIGINT信号来终止它,这就是你看到的错误。

你的代码哪里出问题了?

看这段loop代码:

private void loop(Sequence s) { 
    long currentTime = System.currentTimeMillis(); 
    long lastTime = System.currentTimeMillis(); 
    int x = s.getX(); 
    int y = s.getY(); 
    String n = Integer.toString(s.getNum()); 
    Button button = buttons.get(x).get(y); 
    boolean isFinished = true; 
    while(isFinished) { 
        if(currentTime > lastTime + 400){ 
            button.setText(n); 
            isFinished = false; 
        } else { 
            currentTime = System.currentTimeMillis(); 
        } 
    } 
}

这个while循环会在UI线程上一直循环轮询时间,直到400毫秒过去。这段时间里UI线程啥别的事都干不了,窗口可不就卡死了嘛!再加上show方法里的for循环挨个调用这个阻塞方法,情况只会雪上加霜。

两种靠谱的解决方案

JavaFX专门给定时UI更新准备了工具,别自己写轮询循环啦,试试下面两种方法:

方法一:用Timeline按顺序播放步骤

Timeline是JavaFX用来处理时序动画的工具,刚好适合你的需求——每个步骤间隔400毫秒更新按钮文本,完全不会阻塞UI线程:

public void show() {
    Timeline timeline = new Timeline();
    Duration currentDelay = Duration.ZERO;
    final long STEP_DELAY = 400; // 每个步骤的间隔时间

    for (Sequence s : sequences) {
        int x = s.getX();
        int y = s.getY();
        String numText = Integer.toString(s.getNum());
        Button targetBtn = buttons.get(x).get(y);

        // 创建一个KeyFrame,到点就更新按钮文本
        KeyFrame stepFrame = new KeyFrame(currentDelay, event -> {
            targetBtn.setText(numText);
        });
        timeline.getKeyFrames().add(stepFrame);

        // 累加延迟,让下一个步骤在当前步骤之后执行
        currentDelay = currentDelay.add(Duration.millis(STEP_DELAY));
    }

    // 启动时间线,开始展示步骤
    timeline.play();
}

方法二:后台线程+Platform.runLater(适合需要更灵活控制的场景)

如果你想用后台线程来控制流程,记得必须用Platform.runLater把UI更新任务抛回UI线程——因为JavaFX不允许在非UI线程操作组件:

public void show() {
    new Thread(() -> {
        for (Sequence s : sequences) {
            int x = s.getX();
            int y = s.getY();
            String numText = Integer.toString(s.getNum());
            Button targetBtn = buttons.get(x).get(y);

            // 把UI更新任务提交到UI线程执行
            Platform.runLater(() -> targetBtn.setText(numText));

            // 等待400毫秒,控制步骤节奏
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                // 捕获中断信号,优雅退出线程
                Thread.currentThread().interrupt();
                break;
            }
        }
    }).start();
}

这里要注意:如果线程被中断(比如用户关闭窗口),一定要处理InterruptedException,别让异常乱跑导致程序崩溃。

最后再提个小建议

如果你的数独求解算法本身也挺耗时的,记得把求解逻辑也放到后台线程里,求解完成后再用上面的方法展示过程——别让求解的时候就把UI线程堵死啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:31:03