В настоящее время в нашей кодовой базе есть класс, который использует ключевое слово 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
обращаются вне блока synchronized
?
В идеале это было бы то, что я мог бы сделать с объявлением класса (см. Пример ниже):
@EnsureSynchronized
public class Foo
{
//etc.
}
Или что-то, что я мог бы сделать, когда я объявил экземпляры Foo
(см. Пример ниже):
@EnsureSynchronized
private Foo foo;
Я знаю, действительно ли я хотел бы написать собственное правило FindBugs или PMD, чтобы сделать это, но я надеялся, что нечто подобное уже существует.
Поэтому я прошу васТак что, если бы вы оказались в такой ситуации, как бы вы пытались обеспечить, чтобы к Foo
объектам всегда обращались и изменяли только внутри synchronized
блоков?