我是Java的新手,目前正在阅读《 Java:初学者指南》第六版.我在Java的原子性和内存顺序方面遇到了一些困惑.
在本书涉及多线程的示例中,对共享资源(例如,共享变量)的并发访问不会同步,共享资源也不会被明确标记(例如,原子或易失性或类似的东西).例如,在“尝试此15-1”(第519页)中,对共享变量stopFlag的并发访问未序列化,也未明确标记该变量.
根据this,即使没有特别标记,也保证Java中的某些数据类型是原子的.这在某种程度上解决了关于原子性的考虑.但是记忆顺序如何?默认处理是否暗含顺序一致性,就像对C中的原子类型进行访问时的默认memory_order_seq_cst
处理一样?
以下是该示例中的一些关键代码段.
public class Banner extends Applet implements Runnable {
String msg = " Java Rules the Web ";
Thread t;
boolean stopFlag;
// Initialize t to null.
public void init() {
t = null;
}
// Start thread
public void start() {
t = new Thread(this);
stopFlag = false;
t.start();
}
// Entry point for the thread that runs the banner.
public void run() {
// Redisplay banner
for( ; ; ) {
try {
repaint();
Thread.sleep(250);
if(stopFlag) break;
} catch(InterruptedException exc) {}
}
}
// Pause the banner.
public void stop() {
stopFlag = true;
t = null;
}
// Display the banner.
public void paint(Graphics g) {
char ch;
ch = msg.charAt(0);
msg = msg.substring(1, msg.length());
msg += ch;
g.drawString(msg, 50, 30);
}
解决方法:
没有.
如果使用诸如AtomicInteger之类的数据结构,则是的,set()操作隐含强存储顺序,就像该类中的其他一些操作一样.此处使用的“原子”一词表示该类实现了一组原子操作(例如compareAndSet),这些原子操作通常由子操作组成.顺便提及,这些类型的数据结构通常遵循强存储顺序,并且通过词关联,在这种上下文中使用的“原子”通常表示强存储顺序. (但并非总是如此,例如AtomicInteger中的lazySet和weakCompareAndSet)
回到您的问题,“原子”一词没有这样的含义,仅表示写作不可分割.但这是没有意义的.有意义的是说,对非易失性long或double变量的写操作是“非原子的”,因为它等效于两次写操作(JLS#17.7).其他写操作也不是非原子的.