Java中wait()/notify()报错:当前线程非所有者问题求助
问题分析与解决方案
错误原因:current thread is not owner
wait() 和 notify() 方法的调用必须满足两个硬性条件:
- 必须在同步块/同步方法中执行
- 当前线程必须持有该对象的监视器锁
你的代码直接调用这两个方法,未通过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
相关产品推荐
相关产品推荐

