Java 带锁的单例-可能的死锁?在爪哇
我使用单例记录系统中同时发生的所有事件Java 带锁的单例-可能的死锁?在爪哇,java,singleton,deadlock,database-deadlocks,Java,Singleton,Deadlock,Database Deadlocks,我使用单例记录系统中同时发生的所有事件 public class Singleton { private static Lock dbLock; protected Singleton() {} private static class SingletonHolder { private final static Singleton instance = new Singleton(); } public static Singleton getInstance
public class Singleton {
private static Lock dbLock;
protected Singleton() {}
private static class SingletonHolder {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
public void recordEvent(Event ev) {
dbLock.lock();
try {
database.insert(ev);
} finally {
dbLock.unlock();
}
}
public File lockAndGetDB() {
dbLock.lock();
return database.getFile();
}
public void unlockDB() {
dbLock.unlock();
}
}
每隔几个小时我就要锁定录制事件,以便通过internet发送数据库
file = Singleton.getInstance().lockAndGetDB();
try {
sendViaHTTP(file);
}
finally {
Singleton.getInstance().unlock();
}
是否存在任何可能的僵局?它是线程安全的吗
编辑。(try/finally添加用于通过HTTP发送),但这不是主要问题。问题是,如果有线程等待dbLock.lock();在recordEvent(Event ev)中有我的Singleton.getInstance().unlock();是否能够输入getInstance()代码并解锁?当您以不同的顺序获得锁时,会出现死锁。因为这里只有一个实际的锁,所以问题不存在
在我看来,您的案例更像是一个读写锁的候选者:使用读锁来实现DBMS操作的最大并发性,并在您希望它们停止并发送文件时使用写锁。很可能存在死锁。如果在
database.getFile
或sendViaHTTP
期间发生错误,会发生什么情况?没有try/finally
模式来确保调用Lock.unlock
。实现这样的锁将对该应用程序的性能产生巨大影响。。。你有什么理由不想使用JDBC吗?@JordanDenison我正在Android中实现它。但这是一个普遍的问题java@downvoter请解释一下。无法解释的否决票实际上只是破坏网站。它们不会帮助任何人。当获得锁但从未释放时,也会出现死锁。你所描述的只是死锁的一种形式。@TimBender不,那不是死锁。那只是一把锁。死锁是一个循环的进程链,每个进程都持有下一个进程想要的资源。呃,如果一个线程在释放锁之前崩溃,而其他线程正在等待,那么它们不是停止了吗?大多数人会认为他们可能真的陷入了僵局,但他们错了。这只是一个锁。这是一个错误的例子,我试图使它更简单。是的,当我通过HTTP发送时,当然有try/finally。但这不是问题的关键。获取锁和不获取database.getFile是不可能的。对于您当前的实现,也许该操作永远不会失败。但是,它发生在锁
和try
之间,因此我认为像FindBugs
这样的代码分析器应该会抱怨。