我有这个类,这是文件锁定实用程序的基本方法(不与OS的锁相互作用).我们的想法是拥有一个静态HashMap,它存储对应用程序使用二进制信号量的File对象的一对引用.首次访问新文件时,该对存储在变量中.问题是,.wait()行抛出抛出:IllegalMonitorStateException,我不明白为什么,因为我已经创建了一个项目来测试这个类只有一个线程,所以这是不可能的线程访问方法不拥有对象,不是吗?
public abstract class FileLocker { private static final HashMaplocksMap = 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()
FileLocker.locksMap.get(file).wait();
应该
FileLocker.locksMap.get(file).acquire();
wait
在这种情况下正在等待对象监视器.由于您没有在信号量上同步,即:
Semaphore s = FileLocker.locksMap.get(file); synchronized(s){ s.wait(); }
你得到了例外.在acquire
由信号灯提供和负责处理你同步.
注意你也会遇到相同的情况,notify()
而不是release()