Каркас безопасности потока - PullRequest
4 голосов
/ 11 марта 2010

Следующий класс не является поточно-ориентированным (как доказано в Доказательство следующего кода не является поточно-безопасным )

Существует ли какая-либо инфраструктура, которая может помочь с анализом времени компиляции / времени выполнения и сообщить нам, что следующее не является потокобезопасным?

Для времени компиляции, в идеале в Eclipse, появляется волнистое подчеркивание и говорит нам, что класс не является потокобезопасным?

Во время выполнения любой статический анализ кода обнаружит, что класс не является потокобезопасным?

public class LazyInitRace {
   private ExpensiveObject instance = null;

    public ExpensiveObject getInstance() {
    if (instance == null)
      instance = new ExpensiveObject();
    return instance;
   }
}

Ответы [ 3 ]

4 голосов
/ 11 марта 2010

FindBugs может найти части вашего кода, в которых синхронизация потоков несовместима, то есть вы синхронизируете доступ к полю в одном месте, но не в другом. Он также может выполнять базовую проверку по аннотациям JCIP , но я считаю, что в настоящий момент проверяется только @Immutable.

Я не знаю ни одного инструмента статического анализа, который бы автоматически обнаруживал этот конкретный случай, но я уверен, что он существует.

0 голосов
/ 07 января 2014

Хотя с тех пор, как этот вопрос был задан или получен ответ, прошло много времени, сегодня я сталкивался с этим вопросом при поиске в Google.

Есть ли фреймворк, который может помочь во время компиляции? / run time analysis и сообщите нам, что следующее не является потокобезопасным?

www.contemplateltd.com, они разработали расширенный инструмент статического анализа. Но это не бесплатно.

Для времени компиляции, в идеале в Eclipse, появляется волнистое подчеркивание и говорит нам, что класс не является потокобезопасным?

http://www.checkthread.org/index.html, Это проект с открытым исходным кодом, вы можете увидеть примеры здесь

0 голосов
/ 11 марта 2010

Это классическая проблема, которая называется проблема двойной проверки блокировки .

Проблема в том, что у вас условие гонки , потому что вы проверяете, является ли instance значение null и присваиваете значение. Одно из решений этой проблемы, которое мне нравится в Java:

public class LazyInitRace {
  private static class Container {
    public final static ExpensiveObject INSTANCE = new ExpensiveObject();
  }

  public ExpensiveObject getInstance() {
    return Container.INSTANCE;
  }
}

Способ, которым это работает, заключается в том, что внутренний класс не инициализируется до тех пор, пока на него не ссылаются (что приводит к ленивой загрузке), а загрузка класса является атомарной и поточно-безопасной операцией.

Однако существуют и другие действительные решения.

...