web-dev-qa-db-fra.com

Les méthodes statiques non synchronisées sont-elles sécurisées si elles ne modifient pas les variables de classe statiques?

Je me demandais si vous aviez une méthode statique qui est non synchronisée, mais non modifie-t-elle des variables statiques est-elle thread-safe? Qu'en est-il si la méthode crée des variables locales à l'intérieur? Par exemple, le code suivant est-il thread-safe?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

Donc, si j'ai deux fils appelant cette méthode continuellement et simultanément, l'un avec des chiens (par exemple "dogue allemand" et "taureau") et l'autre avec des chats (par exemple "persan" et "siamois") obtiendrai-je jamais des chats et des chiens dans le même tableau? Ou les chats et les chiens ne seront-ils jamais dans la même invocation de la méthode en même temps?

143
Tobogganski

Cette méthode est 100% thread-safe, elle le serait même si ce n'était pas static. Le problème de la sécurité des threads se pose lorsque vous devez partager des données entre des threads: vous devez prendre en compte l'atomicité, la visibilité, etc.

Cette méthode ne fonctionne que sur paramètres qui résident sur la pile et référence à des objets immuables sur le tas. La pile est intrinsèquement locale au thread, donc aucun partage de données ne se produit, jamais.

Les objets immuables (String dans ce cas) sont également thread-safe car une fois créés, ils ne peuvent pas être modifiés et tous les threads voient la même valeur. D'un autre côté, si la méthode acceptait (modifiable) Date, vous auriez pu avoir un problème. Deux threads peuvent modifier simultanément la même instance d'objet, provoquant des conditions de concurrence et des problèmes de visibilité.

207

Une méthode ne peut être dangereuse pour les threads que si elle modifie un état partagé. Que ce soit statique ou non est sans importance.

28
Konrad Garus

La fonction est parfaitement thread-safe.

Si vous y réfléchissez, supposez ce qui se passerait si c'était différent. Toutes les fonctions habituelles auraient des problèmes de thread si elles n'étaient pas synchronisées, toutes les fonctions de l'API dans le JDK devraient donc être synchronisées, car elles pourraient potentiellement être appelées par plusieurs threads. Et comme la plupart du temps, l'application utilise une API, les applications multithread seraient effectivement impossibles.

C’est trop ridicule pour y penser, alors juste pour vous: Les méthodes ne sont pas thread-safe s’il existe une raison claire pour laquelle il pourrait y avoir des problèmes. Essayez de toujours penser à ce qui se passe s'il y a plusieurs threads dans ma fonction, et si vous aviez un débogueur d'étape et que vous avanceriez l'un après l'autre le premier ... puis le deuxième thread ... peut-être le second encore ... y aurait-il des problèmes? Si vous en trouvez un, ce n'est pas thread-safe.

Sachez également que la plupart des classes de la collection Java 1.5) ne sont pas threadsafe, à l'exception de celles indiquées, comme ConcurrentHashMap.

Et si vous souhaitez vraiment approfondir cette question, examinez de près le mot clé volatile et TOUS ses effets secondaires. Examinez les classes Semaphore () et Lock (), ainsi que leurs amis dans Java.util.Concurrent. Lisez toutes les documentations d'API autour des classes. Cela vaut la peine d'apprendre et de satisfaire aussi.

Désolé pour cette réponse trop élaborée.

12
Daniel

Utilisez le mot clé static avec des méthodes statiques synchronisées pour modifier les données statiques partagées entre les threads. Avec le mot-clé static, tous les threads créés rivaliseront pour une version unique de la méthode.

Utiliser le mot-clé volatile avec des méthodes d'instance synchronisées garantira que chaque thread a sa propre copie des données partagées et qu'aucune lecture/écriture ne s'écoulera entre les threads.

1
clinton

Les objets de chaîne étant immuables est une autre raison du scénario thread-safe ci-dessus. Au lieu de cela, si des objets mutables sont utilisés (par exemple makeMutableArray ..), alors la sécurité des threads sera brisée.

0
harsh