Est-ce qu'un fil à traiter une demande de réseau ultérieure garantie pour voir la valeur d'une variable volatile écrite lors d'une demande antérieure?

Alex W:

J'ai cette question théorique sur le modèle mémoire de Java. Supposons que j'ai un serveur avec ces deux gestionnaires de requêtes dans la classe suivante:

class MyHandlers {
  volatile int someFlag = 0;

  String handleFirstRequest() {
    someFlag = 1;
    return "Hello!";
  }

  String handleSecondRequest() {
    return "value of someFlag: " + someFlag;
  }
}

J'ai aussi un client. Mon client envoie une demande de réseau qui déclenche l'exécution handleFirstRequest. Le client attend jusqu'à ce que la demande finalise. Une fois que la première demande finalise, le client envoie la deuxième demande qui déclenche handleSecondRequest.

Question: Comment le modèle Java mémoire n'empêche la réponse à la deuxième demande d'être "value of someFlag: 0"?

Remarques: Je comprends que, dans la pratique, le fil de manipulation de la deuxième réponse sera toujours voir someFlagque 1.

Si je lis correctement le JMM, il y a un ordre de synchronisation qui est un ordre total, qui commande la lecture volatile et l'écriture (volatile someFlag = 1) dans mon exemple. Si la lecture est postérieure à l'écriture, la lecture verra l'écriture. Est - il possible d'avoir un cas où l'écriture est postérieure à la lecture? Dans ce cas, l'écriture ne se synchronise avec la lecture, et il n'y aurait pas se produit, avant relation entre l'écriture et la lecture. Cela conduirait le fil de manipulation de la deuxième demande de voir someFlagcomme 0. D' où vient mon mal vont comprendre?

Pensées supplémentaires (2020 Mar 2): Le JMM ne se réfère pas à la notion de temps. Actions de synchronisation sont ordonnées selon l'ordre de synchronisation, mais rien dans le JMM dit que l' ordre de synchronisation est le même que l' ordre des actions triées par le temps. Ceci suggère une implémentation Java peut commander la lecture d' someFlag avant l'écriture , même si la lecture a eu lieu après l'écriture en fonction de l'horloge. Il semble que le JMM ne garantit que si la lecture volatile est ordonnée après l'écriture volatile, écrit alors avant l'écriture volatile sont visibles à lit après la lecture volatile.

Alex W:

J'ai trouvé ma réponse!

Section 17.4.3 de la spécification du langage Java stipule ce qui suit:

La cohérence séquentielle est une garantie très forte qui est faite au sujet de la visibilité et de commande dans l'exécution d'un programme. Au sein d' une exécution cohérente séquentielle, il y a un ordre total sur toutes les actions individuelles (comme les lectures et écritures) qui est conforme à l'ordre du programme, et chaque action individuelle est atomique et est immédiatement visible à chaque fil .

Dans le modèle mémoire de Java, des « actions » se réfèrent à des actions inter-fil, qui comprennent les écritures volatiles. Ce paragraphe garantit que toute mise en œuvre Java qui est conforme aux JLS garanties que les écritures volatiles seront immédiatement visibles à d'autres sujets. Dans l'exemple dans le poste d'ouverture, ce paragraphe garantit que la lecture volatile ne peut pas être commandé avant l'écriture volatile.

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=478410&siteId=1
conseillé
Classement