锁定高并发系统



>我在高并发系统中有一个类。该类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;
    }   
}

有几件事很突出:

  1. 我不认为transient关键字意味着您认为它的含义。该关键字与同步无关,仅在序列化类时使用。您可能会将其与 volatile 混淆。顺便说一句,这里也不需要volatile

  2. 单例的延迟初始化可能是不必要的。你为什么不做private static final ClassUtils classUtils = new ClassUtils();?那么你的getInstance((方法不需要同步,只需return classUtils; 它也是线程安全的。您还应该始终将单一实例声明为 final

  3. 不需要
  4. getObjectLock()的整个情况。您只需在this上同步(即将getResolvedClassname变成synchronized方法(,并且会更安全,更干净。

你也可以研究java.util.concurrent.Lock类,看看是否有比在Object上同步更合适的东西,这在现在被认为是糟糕的形式。

这个问题真的有点模糊,我看不出使用单例的目的以及为什么需要同步来完成某些工作。如果它不访问可变状态,则不需要同步。我只能说三个锁(ClassUtils.classClassUtils实例和object(几乎肯定会增加不必要的复杂性。此外,正如 Justin 所指出的,您应该object最终的,然后您不需要同步即可访问它。

你的问题有点笼统。但是,您可以考虑将该值初始化为不可变。许多不可变的初始化值是线程安全的,不需要锁定。

最新更新