2015-01-12 4 views
6

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

class Foo { 
    private Helper helper = null; 
    public Helper getHelper() { 
     if (helper == null) { 
      synchronized(this) { 
       if (helper == null) { 
        helper = new Helper(); 
       } 
      } 
     } 
     return helper; 
    } 
} 

Я хочу, чтобы имитировать эту ситуацию на моем домашнем компьютере. У меня стандартный jdk1.7 и многоядерный процессор. Но я не могу имитировать нарушенное поведение. Я использую этот тест http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckTest.java, который должен имитировать это. Я также создаю часть своего теста, но безуспешно. Вы не представляете, как имитировать ситуацию, когда эта идиома двойной проверки без волатильности нарушена? Таким образом, он возвращает частично созданный класс Helper.

+3

Проблема в том, что вы, вероятно, работаете против процессора x86. Из того, что я знаю, они вызывают барьер StoreLoad после построения объекта, поэтому в этом случае вы не увидите частично построенный объект. Если вы можете получить sparc или другую систему, которая обрабатывает конструкцию, вы, вероятно, сможете увидеть проблему. –

ответ

0

x86, он требует либо класса с большим количеством полей, так что инициализация магазинов перекинуться публикациями, например: http://cs.oswego.edu/pipermail/concurrency-interest/2015-January/013861.html

Или, вы должны munge компилятора для рандомизации команд планировщика. На архитектурах без TSO, таких как ARM, это можно продемонстрировать без каких-либо трюков, см .: http://shipilev.net/blog/2014/safe-public-construction/#_correctness

Смежные вопросы