2010-11-19 21 views
5

Je vois ceci:Est-ce correct? Synchronisé (fil), puis le fil = null dans le bloc synch

// thread is a member of this class 

synchronized(this.thread) 
{ 
    this.thread.running = false; 
    this.thread.notifyAll(); // Wake up anything that was .waiting() on 
    // the thread 
    this.thread = null; // kill this thread reference. 
    // can you do that in a synchronized block? 
} 

Est-il correct de définir le thread=null tout en gardant un verrou sur elle?

J'ai trouvé ce pépite avec un peu de code BB.

+1

Y a-t-il une raison pour laquelle vous n'utilisez pas Thread.interrupt() étant donné que cela est pris en charge par les bibliothèques sous-jacentes? –

Répondre

7

Oui, c'est bien. L'instruction synchronisée prendra une copie de la référence sur laquelle elle se verrouille et utilisera la copie pour déterminer ce qu'elle doit déverrouiller à la fin.

Section 14.19 de la spécification du langage Java est pas vraiment clair à ce sujet, mais il que l'état ne fait l'expression est évaluée au début - et ne mentionne pas l'évaluer à nouveau plus tard.

+0

C'est bien, mais il est douteux que la définition de la référence de thread à null soit une bonne idée. – Adamski

+1

@Adamski: J'ai tendance à avoir une vision relativement forte de ce que je synchronise en premier lieu pour être honnête - je pensais que j'éviterais d'entrer dans ça :) –

+0

D'accord - En fait, IntelliJ m'avertit dans cette situation de la synchronisation sur une variable non finale. – Adamski

3

Il y a une différence:

synchronized(this.thread) 

Vous synchronisez sur l'objet le champ this.thread points

this.thread = null; 

Vous réaffectant le terrain. Vous ne faites rien avec l'objet que vous avez référencé ci-dessus, donc le verrou est toujours valide.

0

Vous pouvez le faire, mais il est presque certain que le code est incorrect pour tout ce qu'il essaie d'obtenir. Post le code entier, et je garantis que c'est évidemment le programmeur ne comprend pas la concurrence.

Ne pas réaffecter une variable utilisée pour la synchronisation.

0

Vous avez seulement un problème si vous avez également un bloc qui attribue une nouvelle valeur à l'enfilage. Dans ce cas, vous avez une condition de concurrence puisque les deux blocs ne se verrouillent pas sur le même objet, mais mettront à jour le même champ et il sera aléatoire quant au bloc qui affecte la dernière valeur.

1

L'expression synchronisée est déréférencée à l'entrée, de sorte que tous les utilisateurs ultérieurs de ce verrou obtiendront une exception NullPointerException. Vous pouvez contourner cela en plaçant une vérification nulle devant le bloc synchronisé, mais vous avez ensuite introduit une condition de concurrence.

+0

'Evaluated' en entrée. – EJP

+3

@EJP plus que évalué - une expression qui évalue à null ne provoque pas une exception NullPointerException. –