锁定高度并发系统

时间:2012-02-23 17:48:31

标签: java concurrency locking deadlock

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

有些事情很突出:

  1. 我不认为transient关键字means what you think it means。该关键字与同步无关,仅在序列化类时使用。您可能会将其与volatile混淆。顺便说一句,此处也不需要volatile

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

  3. 不需要使用getObjectLock()的整个情况。您只需在this上进行同步(即将getResolvedClassname变为synchronized方法),就会更安全,更清洁。

  4. 您还可以调查java.util.concurrent.Lock类,看看是否有比Object上的同步更合适的内容,现在被认为是糟糕的形式。

答案 2 :(得分:0)

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

相关问题