2010-05-06 4 views
3

Pouvons-nous appeler thread_object.start() à partir d'un constructeur de ce même objet?Est-ce une bonne idée de démarrer un thread à partir de son propre constructeur?

Cette approche est-elle une bonne idée?

+2

Constructeur de quoi? Pouvez-vous nous montrer du code pour décrire exactement ce que vous pensez? –

+1

Constructeur de classe qui a étendu la classe Thread ... –

+0

Je pense que vous voulez dire "this.start()" où cela étend Thread "^^ – Hardcoded

Répondre

6

Vous pouvez le faire, mais cela est considéré comme une mauvaise pratique. Il y a un paragraphe sur le démarrage de Threads dans les constructeurs dans ce article.

Comme nicerobot indiqué dans les commentaires, votre question semble être un doublon de this. Jetez un oeil à Heath Borders répondre là.

+0

@Nils: L'article souligne seulement les risques en exposant 'cette' référence lorsque l'objet n'est pas encore dans un état cohérent. Dans le cas des threads, vous pouvez le faire en toute sécurité dans le ctor en créant un thread non interne et en lui fournissant les données dont il a besoin pour l'exécution (et non avec la référence 'this'). –

+0

Excellent! La boîte d'échappement de référence n'est pas sûre pour les threads! –

0

Je suggère de démarrer le fil à l'extérieur, au lieu d'appeler du constructeur. Dans le constructeur, vous ne devriez faire que des choses d'initialisation.

1

C'est une mauvaise pratique, car vous ne pouvez pas être sûr que l'objet est complètement initialisé. Même si vous appelez la méthode start() à la fin du constructeur, cela peut entraîner un désordre.

Sachez que le processeur peut faire des choses hors d'usage:

1: MyObject(){ 
2: aVariable = anyValue; 
3: this.start(); 
4: } 

Le processeur est libre d'exécuter la ligne 3 avant la ligne 2, car ils ne sont pas liés (en une seule façon filetée), de sorte que vous pourrait se retrouver avec des variables non-initialisées (même finales), et d'autres choses inattendues.

+0

En fait, appeler 'thread.start()' est dans une relation * happens-before * avec tout ce qui se passe dans la méthode 'run()', et 'aVariable = anyValue' * se produit avant de démarrer le thread en étant avant dans le constructeur. Votre exemple particulier est donc bien défini et ne causera aucun problème. –

+0

Non, puisque la plupart d'entre nous utilisent des processeurs en désordre, rien n'est défini. JLS: "Il convient de noter que la présence d'une relation avant-événement entre deux actions n'implique pas nécessairement qu'elles doivent se dérouler dans cet ordre dans une implémentation.Si la réorganisation produit des résultats compatibles avec une exécution légale, elle n'est pas illégal." Puisque ces deux instructions ne sont pas directement affectées l'une par l'autre (accès à la même variable ou similaire), la réorganisation est autorisée. – Hardcoded

+0

Lisez la deuxième partie de votre phrase citée: * Si le réordonnancement produit des résultats conformes à une exécution légale *. C'est à dire. ** il doit produire les mêmes résultats **.Le processeur peut faire des choses dans le désordre, mais l'ordre * arrive avant * est encore dérivé de * l'ordre du programme * (c'est-à-dire l'ordre des actions dans un fil écrit dans le programme) et l'ordre de synchronisation (certain actions d'ordonnancement inter-thread, ici démarrage d'un thread). (Relier la section [17.4.3] (http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.3) à 17.4.5 pour plus de détails sur les lecteurs.) –

2

Juste par intérêt - pourquoi étendez-vous le fil? Pourquoi ne pas implémenter Runnable à la place, vous obtenez plus de flexibilité (par exemple, peut être exécuté dans un thread que vous créez ou un ExecutorService, qui est la méthode préférée).

+0

+1 pour implémenter runnable et les API de concurrence Java 5! – justkt

-1

Tant que le fil que vous démarrez n'a pas de référence à this alors tout va bien. Si le thread a une référence à this (soit passé au thread de manière indirecte via une classe interne) alors c'est une mauvaise idée de le démarrer depuis le constructeur car l'objet n'est pas complètement initialisé.

Questions connexes