核心java中的原子问题
这是 Core Java 第 8 版第 757 页的一部分
CAUTION:
public void flipDone() {
done = !done;
}
// notatomic
我不明白为什么它不是原子的。谁能告诉我为什么?谢谢
This is a section from Core Java 8th edition Page 757
CAUTION:
public void flipDone() {
done = !done;
}
// not atomic
I don't understand why it's not atomic. Can any one tell me why? thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
flipDone
方法由计算机分三个不同的步骤执行:在 Java 中,一段代码可能会在多个线程中调用。这些线程应该被认为是并发执行代码。
假设标记为“done”的内存位置最初包含值“false”。考虑两个线程调用
flipDone
,导致以下步骤序列:flipDone
方法被调用两次。正如人们所期望的那样,done
从false
变为true
,然后又回到false
。但由于线程同时执行,这并不是唯一的步骤顺序。请考虑以下顺序:当第一个线程反转其读取的值时,第二个线程同时读取该值。同样,当第一个线程将值写入内存时,第二个线程正在反转它读取的值。当
Thread 2
完成时,done
的值为true。在这里,虽然flipDone
被调用了两次,但done
只被翻转了一次!其中一项更新似乎已丢失。这就是本书试图警告你的问题。The
flipDone
method is executed by the computer in three distinct steps:In Java, a piece of code can potentially be invoked in multiple threads. These threads should be thought of as executing the code concurrently.
Say, memory location labeled
done
contains the valuefalse
initially. Consider two threads callingflipDone
, resulting in the following sequence of steps:The
flipDone
method was called twice.done
went fromfalse
totrue
and then back again tofalse
- as one would expect. But since the threads execute concurrently, this is not the only ordering of steps. Consider this ordering instead:While the first thread is inverting the value it read, the second thread, concurrently, is reading the value. Similarly, while the first thread is writing the value to memory, the second thread is inverting the value it read. When
Thread 2
finishes, the value ofdone
will be true. Here, althoughflipDone
was called twice,done
was flipped only once! One of the updates seem to have been lost. This is the problem that the book is trying to warn you about.这里有三个步骤:
done
done
没有什么可以阻止另一个线程预执行在这一切中间清空。
There are three steps here:
done
done
There's nothing to stop another thread from pre-empting in the middle of all this.
由于两个线程可能同时调用
flipDone()
方法,因此done
变量的状态是不确定的。Because two threads may be calling
flipDone()
method at the same time so the state of thedone
variable is indeterminate.当你执行时
实际发生的是:
如果两个线程一起执行第一步,它们将具有相同的done值,因此它们不会改变它两次,而是只改变它一次。
例如,如果 did 最初为 true,则更改两次后您会期望它仍然为 true,但如果两个线程一起执行步骤 1,则它将为 false。
When you execute
What actually happens is:
If two threads execute the first step together, they are going to have the same value of done, so instead of changing it two times, they will change it only once.
For instance if done was initially true, after changing it two times you'd expect it's still true, but if the two threads execute step 1 together, it will be false.
它不是作为单个不可分割的操作执行,而是由三个离散操作组成的序列 - 获取done的当前值、对值取反、将新值写回done。这是一个读取-修改-写入操作,其中结果状态源自先前的状态。
It does not execute as a single indivisible operation but instead is a sequence of three discrete operations - Fetch the current value of done, Negate the value, Write the new value back to done. It is a
read-modify-write
operation in which the resulting state is derived from the previous state.