那个IllegalMonitorStateException ......线程没有拥有该对象?不可能,只有一个

 曾经的我们太矫情_377 发布于 2023-02-13 10:03

我有这个类,这是文件锁定实用程序的基本方法(不与OS的锁相互作用).我们的想法是拥有一个静态HashMap,它存储对应用程序使用二进制信号量的File对象的一对引用.首次访问新文件时,该对存储在变量中.问题是,.wait()行抛出抛出:IllegalMonitorStateException,我不明白为什么,因为我已经创建了一个项目来测试这个类只有一个线程,所以这是不可能的线程访问方法不拥有对象,不是吗?

public abstract class FileLocker {

    private static final HashMap locksMap = new HashMap<>();

    public synchronized static final void getLock(final File file) {
        if (!FileLocker.locksMap.containsKey(file)) {
            FileLocker.locksMap.put(file, new Semaphore(1, Boolean.TRUE));
        }
        try {
            FileLocker.locksMap.get(file).wait();
        } catch (final InterruptedException e) {
            SysLogger.log(e, "ERR0", SysLogger.Level.CRASH);
        }
        if (file.isDirectory()) {
            for (final File f : file.listFiles()) {
                if (f.isDirectory()) {
                    FileLocker.getLock(f);
                }
            }
        }
    }

    public synchronized static final void releaseLock(final File file) {
        if (file.isDirectory()) {
            for (final File f : file.listFiles()) {
                if (f.isDirectory()) {
                FileLocker.releaseLock(f);
                } else {
                FileLocker.locksMap.get(file).notify();
                }
            }
        }
        FileLocker.locksMap.get(file).notify();
    }
}

我的目的是,这些方法不是同步的,但自从我开始接受这个例外,我把它们改成同步的,因此他们在理论上确保进入他们的线程拥有使用的资源,但它不工作,同样引发异常.

异常跟踪:异常线程"main" java.lang.IllegalMonitorStateException
在java.lang.Object.wait(本机方法)
在java.lang.Object.wait(Object.java:503)
在org.lsp.io.files.
org.lsp.main.Main.main下的FileLocker.getLock(FileLocker.java:18)(Main.java:9)

叫着

FileLocker.getLock(Paths.get("default.xml").toFile());

John Vint.. 6

FileLocker.locksMap.get(file).wait();

应该

FileLocker.locksMap.get(file).acquire();

wait在这种情况下正在等待对象监视器.由于您没有在信号量上同步,即:

Semaphore s = FileLocker.locksMap.get(file);
synchronized(s){
     s.wait();
}

你得到了例外.在acquire由信号灯提供和负责处理你同步.

注意你也会遇到相同的情况,notify()而不是release()

1 个回答
  • FileLocker.locksMap.get(file).wait();

    应该

    FileLocker.locksMap.get(file).acquire();

    wait在这种情况下正在等待对象监视器.由于您没有在信号量上同步,即:

    Semaphore s = FileLocker.locksMap.get(file);
    synchronized(s){
         s.wait();
    }
    

    你得到了例外.在acquire由信号灯提供和负责处理你同步.

    注意你也会遇到相同的情况,notify()而不是release()

    2023-02-13 10:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有