java - AQS中源码疑问
巴扎黑
巴扎黑 2017-04-18 10:48:23
0
3
636

AbstractQueuedSynchronizer类中维护了一个用volatile修饰的state状态,而这个状态有如下的两种修改方法:

  • stateset方法:

protected final void setState(int newState) {
    state = newState;
}
  • CAS方法:

protected final boolean compareAndSetState(int expect, int update) {
    // See below for intrinsics setup to support this
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

那么,我的疑问来了,不是说volatile修饰的变量在多线程的单操作中,能够保证其写后读的可见性,即能保证线程安全,为什么还提供了CAS操作能保证线程安全呢?还是我的理解有问题呢?谢谢各位大牛了!

巴扎黑
巴扎黑

répondre à tous(3)
小葫芦

Il n'y a pas de conflit. setState est juste une opération d'écriture et ne se soucie pas de l'état d'origine. Par exemple, l'état était à l'origine 0. Le thread 1 et le thread 2 lisent respectivement la valeur 0. puis le thread 2 prévoit de le définir sur 2, ce qui peut réussir. Bien que l'état soit déjà 1 et que le thread 2 le sache également, cela n'a pas d'importance. Le thread 2 le définit simplement sur 2. La méthode suivante ne fonctionnera pas.

左手右手慢动作

Oui, il y a un problème avec votre compréhension.

Cela ne signifie pas que les variables volatiles modifiées peuvent garantir la visibilité de la lecture après écriture dans une opération unique multithread, c'est-à-dire que la sécurité des threads peut être garantie

Être capable de garantir la visibilité ne signifie pas que la sécurité des fils peut être garantie. La visibilité et la sécurité des threads ne sont pas le même concept.

l'opération cas peut être divisée en plusieurs petites opérations

  1. Comparez les valeurs actuelles des variables attendues et d'état Si elles sont identiques, passez à l'étape 2. Si elles sont différentes, la méthode se termine.

  2. Attribuer une valeur à la mise à jour de l'état

Si ces deux opérations sont appelées simultanément par plusieurs threads, il y aura des problèmes de sécurité des threads.
La méthode cas utilise ici l'instruction cas du CPU, qui est une opération atomique. Les problèmes de concurrence peuvent être évités.

Peter_Zhu

En bref :

  1. Si vous ne vous fiez pas à la valeur d'origine, vous pouvez utiliser set

  2. Si vous vous fiez à la valeur d'origine, vous pouvez utiliser cas pour la définir. C’est en soi un verrou optimiste.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal