2010-06-01 5 views

Répondre

5

En supposant que le constructeur lui-même est thread-safe, c'est très bien.

Il serait très inhabituel pour un constructeur ne être thread-safe, mais possible ... même si elle est d'appeler le constructeur auto-généré par défaut pour Entity, le constructeur de base peut ne pas être thread-safe . Je ne dis pas qu'il est probable, juste possible :)

Fondamentalement, il n'y a pas de fil magique sécurité appliquée aux méthodes statiques ou méthodes d'instance ou constructeurs. Ils peuvent tous être appelés sur plusieurs threads simultanément, sauf si la synchronisation est appliquée. S'ils n'obtiennent pas ou ne modifient pas les données partagées, ils seront généralement en sécurité - s'ils ont accès à des données partagées, vous devez être plus prudent. (Si les données partagées sont immuables ou seulement lues, c'est généralement correct - mais si l'un des threads le mute, vous devez être très prudent.)

Seuls les initialiseurs statiques (expressions d'initialisation pour les variables statiques et static { ... } directement dans une classe) ont un traitement spécial - la machine virtuelle s'assure qu'ils sont exécutés une fois et une seule fois, en bloquant les autres threads qui attendent que le type soit initialisé.

+0

Pouvez-vous définir, que voulez-vous dire par 'données partagées'? Ce que je comprends que ce serait des champs statiques de la classe 'Enity'! – Akshat

+0

@Achat: Je veux dire toute donnée accessible et modifiée par plusieurs threads. –

+0

Ok, supposons que dans cet exemple, si le constructeur initialise des champs non primitifs finaux et rien d'autre, la méthode 'getInstance()' doit-elle être synchronisée pour la sécurité des threads? – Akshat

4

Cela dépend des détails du constructeur Entity. Si le constructeur Entity modifie les données partagées, alors ce n'est pas le cas.

0

Plusieurs threads peuvent appeler cette méthode et chacun aura une instance unique de 'Entity'. Donc, cette méthode "en soi" est thread safe. Mais s'il y a du code dans le constructeur ou dans l'un des super constructeurs qui n'est pas sûr pour les threads, vous pourriez avoir un problème de sécurité de toute façon.

1

La sécurité des threads concerne l'accès aux données partagées entre différents threads. Le code de votre exemple n'accède pas aux données partagées par lui-même, mais il dépend du fait que le constructeur accède aux données pouvant être partagées entre différents threads.

Il y a beaucoup de problèmes subtils et difficiles à traiter en ce qui concerne la programmation simultanée. Si vous voulez en savoir plus sur la sécurité des threads et la programmation simultanée en Java, je vous recommande vivement le livre Java Concurrency in Practice de Brian Goetz.

2

Il est probablement sûr de thread, mais quel est le point? Si vous utilisez simplement une méthode usine pour rediriger vers le constructeur par défaut, pourquoi ne pas utiliser le constructeur en premier lieu? La question est donc: qu'essayez-vous d'accomplir? Le nom getInstance() suggère un singleton (du moins c'est une pratique courante), mais vous n'avez clairement pas de singleton ici. Si vous voulez un singleton, utilisez une classe de support interne statique comme ceci:

public class Singleton { 

     private Singleton() { 
     } 

     public static Singleton getInstance() { 
      return InstanceHolder.INSTANCE; 
     } 

     private static final class InstanceHolder { 

      public static final Singleton INSTANCE = new Singleton(); 

     } 
    } 

mais si vous ne le faites pas, pourquoi embêter avec une telle méthode d'usine, comme vous n'êtes pas ajouter de valeur (sémantique du nom de la méthode , regroupement d'objets, synchronisation etc) à travers lui

Questions connexes