2011-04-19 4 views
18

По мнению многих, некоторая общая идиома с двойной проверкой блокируется для java, если вы не используете 1.5 или новее и используете ключевое слово volatile.Двойная проверка блокировки в Android

Сломанный перепроверены образец замка:

// Broken multithreaded version 
// "Double-Checked Locking" idiom 
class Foo { 
    private Helper helper = null; 
    public Helper getHelper() { 
    if (helper == null) 
     synchronized(this) { 
     if (helper == null) 
      helper = new Helper(); 
     }  
    return helper; 
    } 
    // other functions and members... 
    } 

Образец приходит из этой статьи, который также предоставляет подробную информацию о том, как это исправить: анализ http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Пью выше для Java VM. Я работаю на Android и часто использую библиотеки, которые используют Double-Checked Locking. Поддерживает ли модель памяти dalvik VM эту идиому?

+0

Возможно, вы догадались, на что я смотрел;) – Snicolas

ответ

10

Ответ на этот вопрос question подразумевает, что модели памяти должны быть одинаковыми и что новая двойная проверенная блокировка идиомы будет работать.

+1

Yup. С добавлением ключевого слова «volatile» это будет работать на uniprocessor (все версии Android) и SMP (3.0 "сотовые" и позже). – fadden

+0

В противном случае, до сотов, возможна проверка двойного замка с нелетучими полями? @Fadden BTW, есть ли какое-либо отражение кеширования вызовов в классе dalvik java.lang.Class? Кэширование я имею в виду, что есть некоторое генерация байт-кода, например, на виртуальной машине Java: stackoverflow.com/a/414823/693752 – Snicolas

+1

Вам нужно использовать какую-то операцию синхронизации ('volatile',' synchronized' и т. Д.), Как показано на Pugh's сайт. Сломанный пример в вопросе, ну, сломан и не должен использоваться. Реализация рефлексии в Dalvik со временем изменилась со временем, поэтому вам нужно будет посмотреть код для данного выпуска, чтобы точно знать, что он делает. Я считаю, что есть некоторое кэширование, но, насколько мне известно, генерация байт-кода не является одним из используемых методов. – fadden

0

Я нашел очень хорошую статью о том, что вопрос: http://www.javamex.com/tutorials/double_checked_locking_fixing.shtml

Он четко заявляет 3 способа исправить DCL. И похоже, что в вашем вопросе поле помощника должно быть объявлено изменчивым, иначе это не сработает.

Когда дело касается использования, то есть RoboGucie в вашем случае, я бы предпочел метод загрузчика класса, упомянутый в статье. Для меня это яснее и эффективнее.