高并发系统中的锁定
我有一个高度并发系统中的课程。该类的方法 getResolvedClassName()
可能会产生死锁。所以我按照以下方式设计它:
public class ClassUtils {
private static ClassUtils classUtils;
private transient Object object = new Object();
private synchronized Object getObjectLock() {
return object;
}
public void getResolvedClassName(Class<?> clazz) {
synchronized (getObjectLock()) {
//some job will be done here
}
}
public synchronized static ClassUtils getInstance() {
if(classUtils == null) {
classUtils = new ClassUtils();
}
return classUtils;
}
}
我这样做的方式正确吗?任何信息都会对我有帮助。
谢谢。
编辑:
public class ClassUtils {
private static final ClassUtils classUtils = new ClassUtils();
private ReentrantLock lock = new ReentrantLock();
public void getResolvedClassName(Class<?> clazz) {
lock.lock();
//some job will be done here
lock.unlock();
}
public static ClassUtils getInstance() {
return classUtils;
}
}
I have a class in a highly concurrent system. A method getResolvedClassName()
of that class can produce deadlock. So I am designing it in the following way:
public class ClassUtils {
private static ClassUtils classUtils;
private transient Object object = new Object();
private synchronized Object getObjectLock() {
return object;
}
public void getResolvedClassName(Class<?> clazz) {
synchronized (getObjectLock()) {
//some job will be done here
}
}
public synchronized static ClassUtils getInstance() {
if(classUtils == null) {
classUtils = new ClassUtils();
}
return classUtils;
}
}
Am I doing it in a right way? Any information will be helpful to me.
Thanks.
Edit:
public class ClassUtils {
private static final ClassUtils classUtils = new ClassUtils();
private ReentrantLock lock = new ReentrantLock();
public void getResolvedClassName(Class<?> clazz) {
lock.lock();
//some job will be done here
lock.unlock();
}
public static ClassUtils getInstance() {
return classUtils;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有几点值得注意:
我不认为
transient
关键字 意味着你认为它意味着什么。该关键字与同步无关,仅在序列化类时使用。您可能会将其与易失性
混淆。顺便说一句,这里也不需要易失性
。单例的延迟初始化可能是不必要的。为什么不直接执行
private static Final ClassUtils classUtils = new ClassUtils();
?那么你的 getInstance() 方法不需要同步,只需返回 classUtils;
它也是线程安全的。您还应该始终将单例实例声明为final
。不需要
getObjectLock()
的整个情况。您可以仅在this
上进行同步(即将getResolvedClassname
转换为synchronized
方法),这样会更安全、更干净。您还可以研究
java.util.concurrent.Lock
类,看看是否有比在Object
上同步更合适的东西,现在这种方式被认为是糟糕的形式。A few things stand out:
I don't think the
transient
keyword means what you think it means. That keyword has nothing to do with synchronization, and is only used when serializing a class. You might be confusing it withvolatile
. Incidentally,volatile
is not needed here either.Lazy initialization of your singleton is probably unnecessary. Why don't you just do
private static final ClassUtils classUtils = new ClassUtils();
? Then your getInstance() method does not need to be synchronized and can justreturn classUtils;
It is also thread safe. You should also always declare singleton instances asfinal
.The whole situation with
getObjectLock()
is not needed. You can just synchronize onthis
(i.e. makegetResolvedClassname
into asynchronized
method) and will be safer and cleaner.You could also investigate the
java.util.concurrent.Lock
classes to see if there is something more suitable than synchronizing on anObject
, which is nowadays considered poor form.这个问题确实有点模糊,我不明白使用单例的目的以及为什么需要同步来完成某些工作。如果它不访问可变状态,则不需要同步。我只能说三个锁(
ClassUtils.class
、ClassUtils
实例和object
)几乎肯定会增加不必要的复杂性。另外,正如 Justin 指出的,您应该将object
设置为最终对象,然后就不需要同步来访问它。This question is really a little vague, I don't see the purpose of using a singleton and why synchronization is required to do some job. If it doesn't access mutable state, it doesn't need synchronization. I can only say that three locks (
ClassUtils.class
,ClassUtils
instance, andobject
) are almost certainly adding unnecessary complexity. Also, as Justin noted, you should makeobject
final, then you won't need synchronization to access it.您的问题有点普遍。但是,您可以考虑将该值初始化为不可变的。许多不可变的初始化值是线程安全的,并且不需要锁定。
Your problem is a bit general. However, you can consider initializing that value as immutable. Many immutable, initialized values are threadsafe, and require no locking.