140 votes

Sont Java initialiseurs statiques thread-safe?

Je suis statique à l'aide d'un bloc de code pour initialiser certains contrôleurs dans un regsitry j'ai. Ma question est donc, puis-je la garantie que cette statique bloc de code ne absolument être appelé qu'une seule fois lorsque la classe est chargée pour la première fois? Je comprends que je ne peux pas garantir quand ce bloc de code sera appelé, Im devinant son lorsque le chargeur de classe de la première charge. Je me rends compte que je pouvais synchroniser sur la classe dans la statique bloc de code, mais je pense que c'est effectivement ce qui se passe de toute façon?

Exemple de code Simple serait;

class FooRegistry {

    static {
        //this code must only ever be called once 
        addController(new FooControllerImpl());
    }

    private static void addController(IFooController controller) { 
        // ...
    }
}

ou devrais-je le faire;

class FooRegistry {

    static {
        synchronized(FooRegistry.class) {
            addController(new FooControllerImpl());
        }
    }

    private static void addController(IFooController controller) {
        // ...
    }
}

202voto

Matthew Murdoch Points 11530

Oui, Java initialiseurs statiques sont thread-safe (première option).

Toutefois, si vous voulez vous assurer que le code est exécuté exactement une fois que vous avez besoin pour vous assurer que la classe n'est chargé que par une seule classe loader. Initialisation statique est effectuée une fois par classe-loader.

12voto

Peter Lawrey Points 229686

C'est une astuce que vous pouvez utiliser pour l'initialisation tardive

enum Singleton {
    INSTANCE;
}

ou pour le pré Java 5.0

class Singleton {
   static class SingletonHolder {
      static final Singleton INSTANCE = new Singleton();
   }
   public static Singleton instance() {
      return SingletonHolder.INSTANCE;
   }
}

Comme le bloc statique dans SingletonHolder sera exécuté une fois dans un thread de manière sécuritaire, vous n'avez pas besoin d'un autre blocage. La classe SingletonHolder ne se charge lorsque vous appelez instance()

4voto

Dans les circonstances habituelles tout en statique et initialiser se passe-avant tout ce qui utilise cette classe, de sorte que la synchronisation n'est généralement pas nécessaire. Cependant, la classe est accessible à tout ce que la statique intiailiser appels (y compris causant d'autres statique initialisers être invoquée).

Une classe peut être chargé par une classe chargée, mais pas nécessairement démarre tout de suite. Bien sûr, une classe peut être chargé par les multiples instances de la classe chargeurs et, de ce fait, plusieurs classes avec le même nom.

3voto

Matt Points 1023

Oui, une sorte de

Un initialiseur statique seulement est appelé à la fois, donc par définition c'est thread-safe -- vous auriez besoin de deux ou plusieurs invocations de l'initialiseur statique pour obtenir même fil de contention.

Cela dit, les initialiseurs statiques sont source de confusion dans de nombreuses autres façons. Il n'y a vraiment pas de l'ordre dans lequel ils sont appelés. C'est vraiment déroutant si vous avez deux classes dont les initialiseurs statiques dépendent les uns des autres. Et si vous utilisez une classe, mais ne pas utiliser ce que l'initialiseur statique sera mis en place, vous n'êtes pas garanti le chargeur de classe invoquera l'initialiseur statique.

Enfin, gardez à l'esprit les objets que vous synchronisez. Je me rends compte que ce n'est pas vraiment ce que vous demandez, mais assurez-vous que votre question n'a pas vraiment vous demander si vous avez besoin de faire addController() thread-safe.

0voto

Mike Pone Points 4840

Oui, les initialiseurs Statiques sont exécutés qu'une seule fois. Lire ceci pour plus d'informations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X