Question

Je suis vraiment nouveau à Java et je lis que synchronized est « très cher » en Java. Tout ce que je veux savoir est ce qui est cher et comment est-il cher?

Merci.

Était-ce utile?

La solution

Peut-être pas aussi mauvais que vous pensez

Il fut terrible (ce qui est peut-être la raison pour laquelle vous avez bien lu qu'il était « très cher »). Ces mèmes peuvent prendre beaucoup de temps pour mourir

  

Quel est le coût de synchronisation?

     

En raison des règles concernant le rinçage du cache et infirmation, un bloc synchronisé dans le langage Java est généralement plus cher que les installations de section critique offerts par de nombreuses plates-formes, qui sont généralement mises en œuvre avec une instruction machine « test et bits » atomique. Même lorsqu'un programme ne contient qu'un seul fil en cours d'exécution sur un seul processeur, un appel de méthode synchronisée est encore plus lent qu'un appel de méthode non synchronisée. Si la synchronisation nécessite effectivement se disputant la serrure, la pénalité de performance est sensiblement plus grande, car il y aura plusieurs commutateurs de fil et des appels système requis.

     

Heureusement, l'amélioration continue de la machine virtuelle Java ont à la fois l'amélioration de la performance globale du programme Java et réduit le coût relatif de la synchronisation avec chaque version, et les améliorations futures sont prévues. En outre, les coûts de performance de synchronisation sont souvent surévalués. Une source bien connue a cité qu'un appel de méthode synchronisée est jusqu'à 50 fois plus lente que l'appel de méthode non synchronisée. Bien que cette déclaration peut être vrai, il est également tout à fait trompeur et a conduit de nombreux développeurs à éviter de synchroniser même dans les cas où il est nécessaire.

Cela dit - la programmation concurrente peut encore être lent, mais pas tant il est purement faute de Java maintenant. Il y a un compromis entre fin et verrouillage grossier. Trop grossier est évidemment mauvais, mais il est possible d'être trop bien aussi, que les serrures ont un non coût nul.

Il est important de tenir compte de la ressource particulière sous contention. disques durs mécaniques sont un exemple où plusieurs threads peuvent conduire à pire performance.

Autres conseils

Il est cher parce que si vous utilisez des fils, et un certain nombre de fils à passer par une section synchronisée de code, seul d'entre eux peut être exécuté à la fois.

Il est comme un goulot d'étranglement.

Il est encore cher lorsque vous utilisez un seul fil, car il doit vérifier de toute façon s'il est autorisé à exécuter.

Si vous réduisez l'utilisation de segments synchronisés votre fil ne devra pas arrêter pour voir si elles peuvent courir (bien sûr, ils ne doivent pas partager des données)

Un aperçu de haut niveau de fonctionnement de la synchronisation se trouvent href="http://en.wikipedia.org/wiki/Monitor_(synchronization)#Implicit_condition_monitors"

http://img20.imageshack.us/img20/2066/monitor28synchronizatioc.png

Un moniteur de style Java

Ce n'est pas spécifique à Java. La synchronisation peut être considéré comme « coûteux » dans un environnement multi-thread si pas fait correctement. Que ce soit particulièrement mauvaise en Java, je ne sais pas.

Il empêche threads d'en même temps si elles utilisent la même ressource. Mais, étant donné qu'ils faire utilisent la même ressource, il n'y a pas de meilleure option (il doit être fait).

Le problème est que les gens protègent souvent une ressource avec une portée trop grande. Par exemple, un programme mal conçu peut synchroniser une gamme entière d'objets, plutôt que chaque élément individuel de la matrice (ou même une partie de la matrice).

Cela signifie qu'un fil essayant de lire l'élément 7 doit attendre une lecture de fil ou d'un élément d'écriture 22. Pas nécessaire. Si la granularité de la synchronisation étaient au niveau de l'élément au lieu du niveau de tableau, ces deux fils ne seraient pas interférer les uns avec les autres.

Seulement lorsque deux fils ont essayé d'accéder à la même élément y aurait-il des conflits de ressources. Voilà pourquoi la règle générale est de protéger seulement comme une ressource petite que possible (sous réserve de limitations du nombre de synchronisations, bien sûr).

Mais, pour être honnête, peu importe combien il est coûteux si l'alternative est la corruption de données en raison de deux fils se disputant une seule ressource. Écrivez votre application correctement et ne vous soucier des problèmes de performance si et quand ils apparaissent ( « d'abord faire fonctionner puis get it travail rapide » est un mantra de mes préférés).

article sur IBM résume en fait très bien les principaux points derrière la synchronisation.

  

En raison des règles concernant le rinçage du cache et infirmation, un bloc synchronisé dans le langage Java est généralement plus cher que les installations de section critique offerts par de nombreuses plates-formes, qui sont généralement mises en œuvre avec une instruction machine « test et bits » atomique. Même lorsqu'un programme ne contient qu'un seul fil en cours d'exécution sur un seul processeur, un appel de méthode synchronisée est encore plus lent qu'un appel de méthode non synchronisé. Si la synchronisation nécessite effectivement se disputant la serrure, la pénalité de performance est sensiblement plus grande, car il y aura plusieurs commutateurs de fil et des appels système requis.

Les autres réponses donnent un bon niveau de détail technique que je ne vais pas tenter de reproduire.

Ce que je vais faire est vous conseille de vérifier les dates des articles (ainsi que la compétence implicite et la conscience de l'auteur). Synchronisation en Java était très lent dans JVMs plus tôt. Cependant, il est beaucoup amélioré récemment, de sorte que la synchronisation est beaucoup sans compétition plus rapide que vous pourriez penser, et la synchronisation est améliorée aussi sans compétition.

Rappelez-vous, cette question ne peut pas d'importance - si vous avez besoin de synchroniser pour assurer l'exactitude, vous besoin pour synchronisent de garantir l'exactitude. Les seules fois où je peux voir la vitesse étant une question est de savoir si vous envisagez de créer une implémentation lockless au lieu (en utilisant le complexe mais très efficace java.util.concurrent.locks.AbstractQueuedSynchronizer ), ou peut-être envisager une autre langue pour votre tâche à la place.

En général, je pense que la meilleure conclusion est que la synchronisation est généralement assez rapide pour utiliser sur une première itération. Comme avec tous les problèmes de performances, le code pour la clarté et l'exactitude d'abord et seulement optimiser ce que vous mesurez être une partie coûteuse de votre application. En règle générale, ce ne sera pas le coût de la synchronisation *.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top