¿Cómo puedo asegurar que un método anulado esté sincronizado


Tengo una clase de código común que es thread safe.

Uno de los métodos de esa clase es abstracto y necesita ser sobrescrito para diferentes implementaciones.

Necesito asegurar o al menos marcar a otros desarrolladores que todas las implementaciones de este método deben ser seguras para subprocesos.

¿Cuál es la mejor manera de hacer esto?

¿Hay una palabra clave o anotación a este efecto?

Ya he probado abstract synchronized pero esa combinación de palabras clave no es permitir.

Author: Vikdor, 2012-10-02

3 answers

No puedes hacerlo directamente. Una cosa que puedes hacer es que el método sea concreto, pero invoca un método abstracto:

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

De esta manera, doFoo() siempre será invocado* bajo la sincronización establecida por foo().

* a menos que alguien lo invoque directamente, por lo que debe nombrarlo y documentarlo para dejar claro que no debe hacerlo.

 25
Author: yshavit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-02 06:20:43

Desde Método sincronizado en la subclase

Sincronizado es el detalle de implementación de un método. Puede anular un método de sincronización con un método sin declararlo como sincronización y viceversa. Lo mismo es cierto para la sobrecarga también.

También puede echar un vistazo a, Un método sincronizado en la superclase adquiere el mismo bloqueo que uno en la subclase.

 1
Author: Amarnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:05

Este enlace al JLS confirma que no podemos mezclar abstracto y sincronizado.

Aunque mucho más débil que una palabra clave o una anotación estándar, pero más fuerte que la documentación: tal vez intente una interfaz de marcador ?

... proporciona un medio para asociar metadatos con una clase donde el language no tiene soporte explícito para dichos metadatos.

Esto es un estiramiento, pero podría ayudar, en que la clase derivada hace una declaración (editar : un nuevo ejemplo prueba la declaración):

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(); } 
}
 0
Author: Michael Easter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-02 07:58:15