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

如何在运行循环的同时保证事件线程正常响应不被阻塞

问题原因分析
  • 第二版代码逻辑错误:nativeMousePressed 中判断 if(program != null) 才创建线程,但初始化时 program 为null,导致首次点击不会创建线程,鼠标松开时直接调用 program.interrupt() 就会触发空指针异常。
  • 第一版代码存在线程复用问题:Java 的Thread实例仅允许调用一次start()方法,第二次按下鼠标重复调用会抛出IllegalThreadStateException异常。
  • 存在线程可见性隐患:Controller.fixAim 没有加volatile修饰,多线程场景下子线程不会主动同步主内存的变量值,就算事件线程修改了fixAim,运行循环的子线程也可能感知不到,导致死循环。
  • 最初的事件线程阻塞原因:所有系统事件回调都是运行在专属的事件分发线程上,如果直接在事件回调方法内写死循环,会占满事件线程的执行资源,后续所有鼠标、键盘事件都无法正常分发,自然收不到nativeMouseReleased回调。
修复方案

第一步:给跨线程访问的静态变量加volatile修饰

修改Controller类中的fixAim定义,保证变量修改对所有线程可见:

public class Controller {
    // 其他原有代码不变
    public static volatile boolean fixAim = false;
    // 若threeClicked也会跨线程修改,同样加volatile修饰
    public static volatile boolean threeClicked = false;
}

第二步:修正事件监听器的逻辑

public class NativeMouseEvent implements NativeMouseListener {
    private Program program;

    @Override
    public void nativeMouseClicked(org.jnativehook.mouse.NativeMouseEvent e) {
    }

    @Override
    public void nativeMousePressed(org.jnativehook.mouse.NativeMouseEvent e) {
        if(e.getButton() == 1 && Controller.threeClicked) {
            Controller.fixAim = true;
            // 仅当线程未创建时才初始化启动,和之前的判断逻辑相反
            if(program == null) {
                program = new Program();
                program.start();
            }
        }
    }

    @Override
    public void nativeMouseReleased(org.jnativehook.mouse.NativeMouseEvent e) {
        Controller.fixAim = false;
        // 先判空再处理,避免空指针
        if(program != null) {
            program.interrupt();
            program = null;
        }
    }
}

第三步:优化子线程的退出逻辑

public class Program extends Thread {
    @Override
    public void run() {
        // 同时判断标志位和线程中断状态,双重保险保证及时退出
        while(Controller.fixAim && !isInterrupted()) {
            System.out.println("test");
            // 可根据需求添加休眠控制执行频率,避免占用过多CPU资源
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // 收到中断信号直接退出循环
                break;
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:12:03