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;
}
}
A few things stand out:
I don’t think the
transientkeyword 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,volatileis 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. makegetResolvedClassnameinto asynchronizedmethod) and will be safer and cleaner.You could also investigate the
java.util.concurrent.Lockclasses to see if there is something more suitable than synchronizing on anObject, which is nowadays considered poor form.