Que signifie «atomique» dans la programmation?


276

Dans le livre Effective Java, il indique:

La spécification du langage garantit que la lecture ou l'écriture d'une variable est atomique sauf si la variable est de type longou double[JLS, 17.4.7].

Que signifie "atomique" dans le contexte de la programmation Java ou de la programmation en général?


24
Une opération à la fois.
Subhrajyoti Majumder

1
une seule opération peut être effectuée sur la variable à la fois.
kaysush


1
je soupçonne que les questions de philosophie appartiennent à codereview.stackexchange.com
Phlip

Notant que certaines variables n'ont pas par défaut de lecture et d'écriture atomiques, les déclarant comme volatile longou volatile doublefaisant lire atomique et écrire atomique.
H2ONaCl

Réponses:


372

Voici un exemple, car un exemple est souvent plus clair qu'une longue explication. Supposons qu'il foos'agit d'une variable de type long. L'opération suivante n'est pas une opération atomique:

foo = 65465498L;

En effet, la variable est écrite en utilisant deux opérations distinctes: une qui écrit les 32 premiers bits, et une seconde qui écrit les 32 derniers bits. Cela signifie qu'un autre thread peut lire la valeur de fooet voir l'état intermédiaire.

Rendre l'opération atomique consiste à utiliser des mécanismes de synchronisation afin de s'assurer que l'opération est vue, à partir de tout autre thread, comme une seule opération atomique (c'est-à-dire non fractionnable en partie). Cela signifie que tout autre thread, une fois l'opération atomique, verra la valeur de fooavant l'affectation ou après l'affectation. Mais jamais la valeur intermédiaire.

Une façon simple de le faire est de rendre la variable volatile :

private volatile long foo;

Ou pour synchroniser chaque accès à la variable:

public synchronized void setFoo(long value) {
    this.foo = value;
}

public synchronized long getFoo() {
    return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized

Ou pour le remplacer par un AtomicLong:

private AtomicLong foo;

75
Cela suppose donc qu'il s'exécute dans un système 32 bits. Et si c'était un système 64 bits? Foo = 65465498L; être atomique alors?
Harke

46
@Harke Si vous utilisez Java 64 bits, oui.
Jeroen

4
Est-ce que cela s'applique également à C # et .NET? Si oui, pour obtenir un comportement atomique, le CLR doit être 64 bits?
Fabiano

5
@Fabiano Cela s'applique et voici comment y parvenir dans .NET car nous n'avons pas le mot-clé synchronisé comme Java. stackoverflow.com/questions/541194/…
The Muffin Man

2
Supposons alors que le thread A attribue une valeur longue, puis à mi-chemin le thread B essaie de le lire. Si l'opération A est atomique, alors le thread B attendra qu'il se termine? Cela signifie que les opérations atomiques fourniront une sécurité implicite des threads?
Teoman shipahi

60

"Opération atomique" signifie une opération qui semble être instantanée du point de vue de tous les autres threads. Vous n'avez pas à vous soucier d'une opération partiellement terminée lorsque la garantie s'applique.


25

C'est quelque chose qui «apparaît au reste du système comme se produisant instantanément», et relève de la catégorisation de la linéarisation dans les processus informatiques. Pour citer cet article lié plus loin:

L'atomicité est une garantie d'isolement des processus concurrents. De plus, les opérations atomiques ont généralement une définition de réussite ou d'échec - elles modifient avec succès l'état du système ou n'ont aucun effet apparent.

Ainsi, par exemple, dans le contexte d'un système de base de données, on peut avoir des `` validations atomiques '', ce qui signifie que vous pouvez pousser un ensemble de modifications de mises à jour vers une base de données relationnelle et ces modifications seront soit toutes soumises, soit aucune d'entre elles dans en cas d'échec, de cette façon les données ne se corrompent pas, et suite aux verrous et / ou files d'attente, la prochaine opération sera une écriture ou une lecture différente, mais seulement après coup . Dans le contexte des variables et du threading, c'est à peu près la même chose, appliqué à la mémoire.

Votre citation souligne que ce comportement ne doit pas être attendu dans tous les cas.


15

Je viens de trouver un article Atomic vs. Non-Atomic Operations qui m'a été très utile.

"Une opération agissant sur la mémoire partagée est atomique si elle se termine en une seule étape par rapport aux autres threads.

Lorsqu'un stockage atomique est effectué sur une mémoire partagée, aucun autre thread ne peut observer la modification à moitié terminée.

Lorsqu'une charge atomique est effectuée sur une variable partagée, elle lit la valeur entière telle qu'elle est apparue à un instant donné. "


14

Si vous avez plusieurs threads exécutant les méthodes m1 et m2 dans le code ci-dessous:

class SomeClass {
    private int i = 0;

    public void m1() { i = 5; }
    public int m2() { return i; }
}

vous avez la garantie que tout thread appelant m2lira 0 ou 5.

En revanche, avec ce code (où iest un long):

class SomeClass {
    private long i = 0;

    public void m1() { i = 1234567890L; }
    public long m2() { return i; }
}

un thread appelant m2pourrait lire 0, 1234567890L, ou une autre valeur aléatoire car l'instruction i = 1234567890Ln'est pas garantie d'être atomique pour un long(une machine virtuelle Java peut écrire les 32 premiers bits et les 32 derniers bits en deux opérations et un thread peut observer ientre les deux) .


pourquoi pensez-vous que "long" pose problème alors que "int" ne pose pas de problème? Veuillez voir ici geekswithblogs.net/BlackRabbitCoder/archive/2012/08/09/…
onmyway133

1
Les assignations longues et doubles @entropy ne sont pas garanties atomiques en Java. Vous pouvez donc lire un long où seulement la moitié des bits ont été mis à jour suite à une affectation.
assylias

0

En Java, la lecture et l'écriture de champs de tous types sauf long et double se produisent atomiquement, et si le champ est déclaré avec le modificateur volatile, même long et double sont lus et écrits atomiquement. Autrement dit, nous obtenons 100% soit ce qui était là, soit ce qui s'est passé là-bas, ni aucun résultat intermédiaire dans les variables.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.