Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.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_Visibility_Safe Publication - Fatal编程技术网

Java 在这种情况下,是否永远不会抛出此断言错误?

Java 在这种情况下,是否永远不会抛出此断言错误?,java,multithreading,concurrency,visibility,safe-publication,Java,Multithreading,Concurrency,Visibility,Safe Publication,首先是代码,来自JCIP清单和 我的意思是,在这种情况下不会抛出AssertionError,因为Thread.start()发生在担保之前。注释的System.out.printlns都打印main,这意味着主线程是,它通过在while(true)循环中的线程上创建并调用start生成所有后面的线程 由于这是创建并初始化Holder的线程,所有后续线程都可以安全地成为一个完全可见的Holder,因为有了before保证。我说得对吗 我甚至试着运行这段代码很长时间,没有断言错误 然而,如果ma

首先是代码,来自JCIP清单和

我的意思是,在这种情况下不会抛出AssertionError,因为Thread.start()发生在担保之前。注释的System.out.printlns都打印main,这意味着主线程是,它通过在while(true)循环中的线程上创建并调用start生成所有后面的线程

由于这是创建并初始化Holder的线程,所有后续线程都可以安全地成为一个完全可见的Holder,因为有了before保证。我说得对吗

我甚至试着运行这段代码很长时间,没有断言错误

然而,如果main如下所示,那么我相信断言错误是可能的

 public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().getName());
        StuffIntoPublic t = new StuffIntoPublic();
        new Thread(() -> t.initialize() ).start();
        while (true) {
            new Thread(() -> { t.holder.assertSanity(); }).start();
        }
    }

是的,这是安全的,因为
Thread#start
保证以前发生过。更详细地说:在
线程#开始
之前发生的对任何变量的任何读/写(如果您愿意,我倾向于按程序顺序进行上述思考),也将在该线程内的任何操作之前发生(它是
运行
方法)

事实上,如果之前没有发生过(允许重新排序),并且程序执行允许这些潜在的重新排序,那么这可能会中断并抛出错误。我甚至倾向于说,在弱内存模式下使用合适的CPU(假设您使用的是英特尔,这是一种强内存模式)可能会增加这种可能性,但我不确定

因此,据我所知,操作将按以下顺序进行:首先,发布引用将使用变量
n
重新排序(之前没有发生过,因此这是允许的)。Thread1创建了一个
Holder
的实例。Thread2看到发布的引用并调用该方法。它将变量
n
读取为
0
(请记住,发生了重新排序,并且
n
尚未写入,因此默认值为
0
),因此它会执行
=检查,但创建
保持架的Thread1将
n
写入
12
,例如,在Thread2再次读取它之前(在
!=n
部分)。所以这可能会失败


将值设置为final将解决这一问题,因为它引入了正确的内存障碍,或者发生在规则之前

你从哪里拿到的
SafePublication
课程代码?我写了那个代码然后我不明白你的问题实际上,
SafePublication
是不安全的,因为
holder=newholder(42)
是不安全的发布。在SafePublication的主要方法中,是否可以抛出AssertionError?
 public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().getName());
        StuffIntoPublic t = new StuffIntoPublic();
        new Thread(() -> t.initialize() ).start();
        while (true) {
            new Thread(() -> { t.holder.assertSanity(); }).start();
        }
    }