Dois-je synchroniser l'accès à des structures de données thread-safe encapsulées en Java?
-
19-09-2019 - |
Question
Dire que j'ai quelque chose comme ça (et je fais)
class QueBean extends JPanel {
private Queue queue = new LinkedBlockingQueue();
public Object poll(){
return queue.poll();
}
}
avec certains d'entre eux qui courent sur leurs propres fils
class ConsumerBean extends JPanel implements Runnable{
private QueBean queBean;
public synchronized run(){
while (true) {
Object result = queBean.poll();
if (result != null) {
jResultTextField.setText("got one");
}
wait(500);
}
}
}
Si mon poll()
dans le QueBean
être synchronized
ou non?
La solution
Synchronisation externe n'est pas nécessaire dans ce cas. Lisez le contrat BlockingQueue
:
implémentations sont BlockingQueue thread-safe. Toutes les méthodes qui font la queue atteindre leurs effets à l'aide atomiquement serrures ou autres formes de le contrôle de concurrence.
Autres conseils
Il y a un problème de filetage, mais pas celui que vous pensez -. Le code affiché est presque certainement illégal et finira par bloquer
L'une des règles fondamentales de Swing est qu'un seul thread est autorisé à toucher « réalisé » composants. (Moyens réalisés à l'écran ou « presque » à l'écran).
jResultTextField.setText("got one");
L'intérieur d'un fil est assez sûr d'être mal - vous ne pouvez pas le faire. Consultez invokeLater ou invokeAndWait pour obtenir vos mises à jour d'écran sur votre fil AWT.
Par ailleurs - il se sent drôle d'avoir des fils dans tout ce qui réserve un composant - voir qui me conduisent à chercher immédiatement pour obtenir où le conflit était, mais il devrait faire tout programmeur Java depuis longtemps mal à l'aise à glance-- Je vous suggère de diviser vos cours et quelques séparer complètement la partie qui anime votre interface graphique (Controller) à partir de l'interface utilisateur graphique (View) ..
Non. Il n'y a pas besoin. Étant donné que votre méthode de poll
ne fait rien d'appeler une méthode de thread-safe, il n'y a aucune possibilité de corruption de données.
Vous n'avez pas besoin de faire cela, tant que queue
ne change pas QueBean
.
En outre, à moins que vous essayez de mettre en œuvre une sorte de taux limitng trivial, vous n'avez pas besoin wait(500)
dans votre code. Il est superflu en raison du blocage d'être de file d'attente.