Блокировка в высоко параллельной системе - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть класс в очень параллельной системе.Метод 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 ]

3 голосов
/ 23 февраля 2012

Этот вопрос действительно немного расплывчатый, я не вижу цели использования синглтона и почему для выполнения какой-либо работы требуется синхронизация. Если он не обращается к изменяемому состоянию, он не нуждается в синхронизации. Я могу только сказать, что три блокировки (ClassUtils.class, ClassUtils instance и object) почти наверняка добавляют ненужную сложность. Также, как заметил Джастин, вы должны сделать object final, тогда вам не потребуется синхронизация для доступа к нему.

3 голосов
/ 23 февраля 2012

Несколько вещей выделяются:

  1. Я не думаю, что ключевое слово transient 1006 * означает то, что вы думаете, оно означает . Это ключевое слово не имеет ничего общего с синхронизацией и используется только при сериализации класса. Возможно, вы путаете это с volatile. Кстати, volatile здесь тоже не нужен.

  2. Ленивая инициализация вашего синглтона, вероятно, не нужна. Почему бы тебе просто не сделать private static final ClassUtils classUtils = new ClassUtils();? Тогда ваш метод getInstance () не нуждается в синхронизации и может просто return classUtils; Он также поточно-ориентирован. Вы также должны всегда объявлять экземпляры-одиночки как final.

  3. Вся ситуация с getObjectLock() не нужна. Вы можете просто синхронизировать на this (то есть превратить getResolvedClassname в метод synchronized), и это будет безопаснее и чище.

Вы также можете исследовать классы java.util.concurrent.Lock, чтобы увидеть, есть ли что-то более подходящее, чем синхронизация на Object, который в настоящее время считается плохой формой.

0 голосов
/ 23 февраля 2012

Ваша проблема немного общая . Однако вы можете рассмотреть возможность инициализации этого значения как неизменяемого. Многие неизменяемые инициализированные значения являются потокобезопасными и не требуют блокировки.

...