Подтвердить что ты не робот

Как я могу обеспечить синхронизацию переопределенного метода

У меня есть класс общего кода, который является потокобезопасным.

Один из методов этого класса является абстрактным и должен быть переопределен для разных реализаций.

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

Каков наилучший способ сделать это?

Есть ли ключевое слово или аннотация для этого?

Я уже пробовал abstract synchronized, но эта комбинация ключевых слов не разрешена.

4b9b3361

Ответ 1

Вы не можете сделать это напрямую. Одна вещь, которую вы можете сделать, - это конкретный метод, но вызывать абстрактный метод:

public synchronized final void foo() {
    doFoo();
}
protected abstract void doFoo();

Таким образом, doFoo() всегда будет вызываться * при синхронизации, установленной foo().

*, если только кто-то не вызывает его напрямую, поэтому вы должны называть его и документировать, чтобы он дал понять, что они не должны.

Ответ 2

От Синхронизированный метод в подклассе

Синхронизированная - это деталь реализации метода. Вы можете переопределить метод синхронизации с помощью метода, не объявляя это как синхронизацию и наоборот. То же самое относится и к перегрузке.

Вы также можете взглянуть на Синхронный метод в суперклассе получает тот же замок, что и один в подклассе.

Ответ 3

Эта ссылка на JLS подтверждает, что мы не можем смешивать абстрактные и синхронизированные.

Хотя гораздо слабее ключевого слова или стандартной аннотации, но более сильной, чем документация: возможно, попробуйте Маркерный интерфейс?

... предоставляет средство для связывания метаданных с классом, где язык не имеет явной поддержки для таких метаданных.

Это растяжка, но может помочь в том, что производный класс делает объявление ( edit: новый пример проверяет декларацию):

interface EatMethodIsThreadSafe {}

abstract class Animal {
    public Animal() {
        if (! (this instanceof EatMethodIsThreadSafe)) { 
            throw new IllegalArgumentException("eat method must be thread safe");
        }
    }
    public abstract void eat();
}

public class Bear extends Animal implements EatMethodIsThreadSafe {
    public synchronized void eat() {}
    public static void main(String...args) { Bear b = new Bear(); } 
}