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

Java中wait()/notify()报错:当前线程非所有者问题求助

问题分析与解决方案

错误原因:current thread is not owner

wait() 和 notify() 方法的调用必须满足两个硬性条件:

  1. 必须在同步块/同步方法中执行
  2. 当前线程必须持有该对象的监视器锁

你的代码直接调用这两个方法,未通过synchronized获取对应对象的锁,因此抛出该异常。此外,原检测线程仅做单次检测,无法持续监控软件状态,无法实现"软件运行时暂停执行"的需求。

修正方案:持续监控+正确线程同步

我们可以通过共享锁对象配合循环检测,实现软件状态的持续监控与线程间的同步控制。以下是优化后的完整代码:

优化后的代码实现

public void executeTravauxSelectionnes(String entreeUtilisateur) {
    // 共享锁对象,用于线程间同步通信
    final Object lock = new Object();
    String softwarePath = propert.getProperty("softwarePath");

    // 启动持续监控线程
    new Thread(() -> {
        while (true) {
            // 检测目标软件是否在运行
            boolean softwareRunning = ProcessHandle.allProcesses()
                    .filter(p -> p.info().command().isPresent())
                    .anyMatch(p -> p.info().command().get().contains(softwarePath));

            synchronized (lock) {
                if (!softwareRunning) {
                    System.out.println("目标软件已关闭,准备执行任务");
                    // 唤醒等待的主线程
                    lock.notify();
                    break;
                } else {
                    System.out.println("目标软件正在运行,等待关闭...");
                    try {
                        // 每1秒检测一次,避免空轮询浪费资源
                        lock.wait(1000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
        }
    }).start();

    // 主线程等待,直到监控线程确认软件已关闭
    synchronized (lock) {
        try {
            lock.wait();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
    }

    // 分割用户输入的任务列表
    String[] travauxSelectionnes = entreeUtilisateur.split(",");
    int nombreDeThreads = travauxSelectionnes.length;
    ExecutorService executor = Executors.newFixedThreadPool(nombreDeThreads);

    // 遍历处理选中的任务
    for (String travail : travauxSelectionnes) {
        if (travail.matches("\\d+")) {
            int travailNumber = Integer.parseInt(travail.trim());
            executor.execute(() -> executeTravail(travailNumber));
        } else if (travail.matches("\\d+-\\d+")) {
            String[] range = travail.split("-");
            int start = Integer.parseInt(range[0].trim());
            int end = Integer.parseInt(range[1].trim());
            for (int i = start; i <= end; i++) {
                int travailNumber = i;
                executor.execute(() -> executeTravail(travailNumber));
            }
        } else {
            System.out.println("无效的任务编号: " + travail);
        }
    }

    executor.shutdown();
}

关键优化点说明

  • 同步锁规范使用:所有wait()和notify()调用都包裹在synchronized(lock)块中,确保当前线程持有锁
  • 持续状态监控:监控线程通过循环每秒检测一次软件状态,直到软件关闭才终止
  • 资源友好型等待:使用wait(1000)让监控线程在等待时释放CPU资源,避免空轮询
  • 主线程阻塞控制:主线程启动监控后立即进入等待,仅在软件关闭后才继续执行任务逻辑

内容的提问来源于stack exchange,提问作者Tanguy-Trotin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:04:55