Java 可重入写回挂起
知道这个构造函数为什么无限期挂起吗?我正在尝试创建一个线程安全的单例Java 可重入写回挂起,java,java.util.concurrent,reentrantreadwritelock,Java,Java.util.concurrent,Reentrantreadwritelock,知道这个构造函数为什么无限期挂起吗?我正在尝试创建一个线程安全的单例 private RWLockedSingleton() { lock.writeLock().lock(); System.out.println("we're done!"); isComplete = true; lock.writeLock().unlock(); } 顺便说一句,我意识到最好将锁放在静态getter中;我只是想知道在构造函数中使用锁是否本质上是错误的刚刚注意到,在静态g
private RWLockedSingleton() {
lock.writeLock().lock();
System.out.println("we're done!");
isComplete = true;
lock.writeLock().unlock();
}
顺便说一句,我意识到最好将锁放在静态getter中;我只是想知道在构造函数中使用锁是否本质上是错误的刚刚注意到,在静态getter中,我在放入构造函数之前获得了lock.readLock上的锁 根据JavaDoc,如果线程有读卡器锁,则不允许升级为写锁。我本以为会出现异常或错误,但在readLock解锁之前暂停线程可能会有有效的用途。作为参考,如果构造函数试图获取writeLock,以下操作将不起作用
public static RWLockedSingleton getSingleton() {
lock.readLock().lock();
RWLockedSingleton ref = null;
if (singleton == null) {
singleton = new RWLockedSingleton();
ref = singleton;
}
lock.readLock().unlock();
return ref;
};
依我看,锁定构造函数几乎总是不正确的。有一个很好的理由,您不能将
同步的添加到构造函数中。您应该锁定调用构造函数的方法
如果您持有readLock(),即使它在同一个线程中,也可以让writeLock()永远等待
创建延迟加载、线程安全的单例的最简单也是最有效的方法是使用enum
enum Singleton {
INSTANCE;
}
请展示一个简短但完整的程序来演示问题。您可能还想问问自己,为什么要使用ReentrantReadWriteLock
,而不是使用静态初始化保证来实现线程安全的单例。最好这样做:试试{lock.writeLock().lock();//做任何您想做的事情}最后{lock.writeLock().unlock();}
@jon skeet我读到了关于静态init方法的内容,但我只是想在代码中明确多线程。@Eddy:听起来你在无缘无故地增加复杂性(似乎是以一种破烂的方式)。永远等待确实是我的问题。。。感谢您的提示,最简单的解决方案效果最好。使用枚举避免了显式锁的需要,但仍然是线程安全的。