Есть ли в Java механизм времени компиляции, чтобы попытаться гарантировать, что использование определенного класса всегда синхронизировано?

В настоящее время в нашей кодовой базе есть класс, который использует ключевое слово synchronized на уровне метода для обеспечения согласованности данных в многопоточных операциях. Это выглядит примерно так:

public class Foo
{
   public synchronized void abc() { ... }

   public synchronized void def() { ... }

   //etc.
}

Приятно то, что любой, кто использует класс, получает синхронизацию бесплатно. Когда вы создаете экземпляр Foo , вам не нужно помнить о доступе к нему внутри блока synchronized или чего-то подобного.

К сожалению, похоже, что синхронизация на уровне методов больше не поможет. Вместо этого нам придется начать синхронизацию на самом Foo . Я не думаю, что что-то вроде java.util.concurrent.AtomicReference тоже его сократит. Я хочу убедиться, что никто другой не коснется экземпляра Foo , пока выполняется конкретная (и, возможно, довольно продолжительная) операция. Итак, теперь у нас в коде будут такие блоки:

Foo foo = new Foo(); //this got created somewhere

//somewhere else entirely
synchronized(foo)
{
   //do operation on foo
   foo.doStuff();
   foo.doOtherStuff();
}

Итак, главное, что меня беспокоит, это то, что я и несколько разработчиков разделяем этот код. Объекты Foo довольно распространены.Поскольку мы больше не получаем синхронизацию бесплатно на уровне метода, мы должны ВСЕГДА не забывать обращаться к объекту Foo внутри блока synchronized .

Итак, мой вопрос: есть ли в Java какой-либо механизм (встроенный или сторонний), позволяющий мне генерировать предупреждения или ошибки во время компиляции, если к экземпляру Foo обращаются за пределами синхронизированный блок ?

В идеале это было бы что-то, что я мог бы сделать с объявлением класса (приведенный ниже пример):

@EnsureSynchronized
public class Foo
{
   //etc.
}

Или что-то, что я мог бы сделать, объявляя экземпляры Foo (составленный пример ниже):

@EnsureSynchronized
private Foo foo;

Я знаю, что если бы я действительно этого хотел, я, вероятно, мог бы написать собственное правило FindBugs или PMD для этого, но я надеялся, что что-то подобное уже существует.

Итак, я спрашиваю вас, сообщество SO, если бы вы оказались в такой ситуации, как бы вы попытались обеспечить доступ к объектам Foo и их изменение только внутри синхронизированных блоков?

7
задан Brent Writes Code 13 October 2011 в 15:21
поделиться