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
相关产品推荐
相关产品推荐

