Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 原子变量保证内存可见性吗?_Java_Multithreading_Concurrency_Atomicity_Memory Visibility - Fatal编程技术网

Java 原子变量保证内存可见性吗?

Java 原子变量保证内存可见性吗?,java,multithreading,concurrency,atomicity,memory-visibility,Java,Multithreading,Concurrency,Atomicity,Memory Visibility,关于内存可见性的小问题 代码样本1: class CustomLock { private boolean locked = false; public boolean lock() { if(!locked) { locked = true; return true; } return false; } } class CustomLock { private

关于内存可见性的小问题

代码样本1:

class CustomLock {

    private boolean locked = false;

    public boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
class CustomLock {

    private boolean locked = false;

    public synchronized boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
   public static class CustomLock {
    private AtomicBoolean locked = new AtomicBoolean(false);

    public boolean lock() {
        return locked.compareAndSet(false, true);
    }
}
这段代码在多线程环境中容易出现错误,首先是因为“if-then-act”不是原子的,其次是因为潜在的内存可见性问题,例如threadA将字段设置为true,但后来希望读取字段值的threadB可能看不到,而仍然看到值false

最简单的解决方案是使用synchronized关键字,如CodeSample2

代码样本2:

class CustomLock {

    private boolean locked = false;

    public boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
class CustomLock {

    private boolean locked = false;

    public synchronized boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
   public static class CustomLock {
    private AtomicBoolean locked = new AtomicBoolean(false);

    public boolean lock() {
        return locked.compareAndSet(false, true);
    }
}
现在,如果我想使用一个原子变量,比如一个原子布尔(这个问题适用于所有的原子变量)

代码样本3:

class CustomLock {

    private boolean locked = false;

    public boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
class CustomLock {

    private boolean locked = false;

    public synchronized boolean lock() {
        if(!locked) {
            locked = true;
            return true;
        }
        return false;
    }
}
   public static class CustomLock {
    private AtomicBoolean locked = new AtomicBoolean(false);

    public boolean lock() {
        return locked.compareAndSet(false, true);
    }
}
除了更好的性能考虑,我们可以看到,现在我们已经使用原子布尔实现了与CodeSample1中的“if-then-act”类似的逻辑。 代码在逻辑上做什么并不重要,我的问题是如果两个线程几乎同时调用CodeSample3中的lock()方法会怎么样,虽然很明显,现在对字段的任何写操作都将以原子方式完成,但原子布尔的使用是否也能保证内存可见性

对不起,说来话长,我只是想确保我的理解尽可能清楚,谢谢各位…

是的,根据:

compareAndSet和所有其他读取和更新操作(如Get和Increment)都具有读取和写入易失性变量的内存效应

我的问题是,如果两个线程几乎同时调用CodeSample3中的lock()方法,那么会怎么样?很明显,对字段的任何写入操作现在都将以原子方式完成,但使用原子布尔值是否也能保证内存可见性

对于
AtomicBoolean
,要同时处理来自不同线程的多个操作,必须保证内存可见性。它可以做出保证,因为它包装了一个
volatile
字段。这是
volatile
的语言语义,它确保跨越内存障碍,以便多个线程看到最新的值,并且任何更新都将发布到主内存


顺便说一句,你的
lock(…)
方法应该准备好
tryLock(…)
,因为它可能无法获得锁。

@JamesJenkins实际上,当你有问题时,阅读文档通常非常有用。不管它是否包装了实现细节,文档都是可以查看的地方。您可以使用原子的
synchronized
方法,但如果在其中更新的共享数据未在同一个锁上同步就被公开,则不存在可见性保证我认为我对错误答案发表了评论:|抱歉