- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
首先是代码,来自 JCIP list http://jcip.net/listings/StuffIntoPublic.java和 http://jcip.net/listings/Holder.java
public class SafePublication {
public static void main(String[] args) throws InterruptedException {
// System.out.println(Thread.currentThread().getName());
StuffIntoPublic t = new StuffIntoPublic();
t.initialize();
while (true) {
new Thread(() -> { t.holder.assertSanity(); }).start();
}
}
}
//@author Brian Goetz and Tim Peierls
class StuffIntoPublic {
public Holder holder;
public void initialize() {
// System.out.println(Thread.currentThread().getName());
holder = new Holder(42);
}
}
//@author Brian Goetz and Tim Peierls
class Holder {
private int n;
public Holder(int n ) {
this.n = n;
}
public void assertSanity() {
if (n != n) {
throw new AssertionError("This statement is false.");
}
}
}
我是说在这种情况下永远不会抛出 AssertionError,因为 Thread.start() 发生在保证之前。注释的两个 System.out.printlns 都打印 main,这意味着主线程是通过在 while(true) 循环中的线程上创建和调用 start 来生成所有后续线程。
由于这是创建和初始化 Holder 的线程,因此由于发生前保证,所有后续线程都可以安全地成为完全可见的持有者。我说得对吗?
我什至尝试运行这段代码很长时间,但没有断言错误。
但是,如果 main 如下所示,那么我相信有可能出现 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();
}
}
最佳答案
是的,这是安全的,因为 Thread#start
保证 happens-before。更罗嗦一点:在 Thread#start
之前发生的任何对任何变量的读/写(如果你愿意,我倾向于按程序顺序考虑 above),也会发生 < em>在该线程中的任何操作之前(它是run
方法)。
事实上,如果之前没有发生(允许重新排序)并且程序执行允许这些潜在的重新排序,那可能会发生中断并抛出该错误。我什至倾向于说 和 与弱内存模型一起使用的适当 CPU(假设您使用的是 Intel,这是一种强内存模型)可能会增加这种机会,但我不确定。
因此,据我所知,操作将按以下顺序进行:首先,发布引用用变量 n
重新排序(没有 happens-before,所以这是允许的)。 Thread1 创建了一个 Holder
的实例。 Thread2 看到已发布的引用并调用该方法。它读取变量 n
为 0
(记住重新排序发生并且 n
尚未写入,因此默认值为 zero
),所以它会执行 !=
检查,但是 Thread1 创建了 Holder
,写入 n
为 12
例如 before Thread2 再次读取它(在 !=n
部分)。所以这可能会失败。
将值设置为 final
可以解决这个问题,因为它引入了正确的内存屏障,或者 happens-before 规则。
关于java - 在这种情况下永远不会抛出这个 AssertionError 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48138107/
我在一个Spring Boot应用程序中有以下路线。并进行以下测试。第二个测试的目的是验证如果将消息“{}”发送到DIRECT:LOG终结点,它将超出To(Bean-validator://check
这是我的简单 test.py 脚本: import argparse parser = argparse.ArgumentParser('A long string that goes on and
我在Android Studio的另一台计算机上打开我的Kotlin项目,并在事件日志中遇到错误: AssertionError: Root package must be initialized R
我在redux (redux@3.7.2) 中使用combineReducer 方法时遇到错误。当我只使用一个 reducer 时,相同的代码将起作用。 Running code here 代码 co
我目前正在对我的 Controller 的一个方法进行单元测试。只是尝试测试该方法是否返回正确的字符串。 @RequestMapping(value = "/createTestscenario",
我收到错误: java.lang.AssertionError: expected: learning.java.advancedoop2.MyComplex but was: learning.ja
这个问题在这里已经有了答案: How can I check if two ArrayList differ, I don't care what's changed (6 个答案) 关闭 7 年前
我正在准备 OCP 7,我在其中一本证书书上遇到了这篇文章。 To discourage you from trying to substitute an assertion for an excep
我有一个 index.js 文件,它实现了一个 forEach 助手,如下所示: var images = [ { height: 10, width: 30 }, { height: 20,
作为实验,我 try catch 失败的断言。 try: assert 1==2 except Exception as e: print e 为什么没有显示? 最佳答案 >>> try: asser
我在 django 中创建了一个调用函数的命令。该函数执行 django orm 调用: def get_notes(): notes = Note.objects.filter(number
我有一个用户类和一个主题类。用户类可以创建一个主题,将一个主题添加到主题的字典中,并且应该能够返回主题的字典。我是 python 的新手,所以我在 python 逻辑/语法方面遇到了问题 class
我正在尝试创建一个基于用户身份验证限制结果的 View 。出于某种原因,列表切片总是导致 AssertionError Cannot filter a query once a slice has b
我正在使用带有注释处理器的内部 sun API (com.sun.tools.javac) 修改现有类。我能够使用以下代码生成 MethodDecl 并将其添加到 ClassDecl: JCTree.
这是原代码 //@author Brian Goetz and Tim Peierls @ThreadSafe public class SafePoint { @GuardedBy("thi
我能够访问 PasswordChangeSerializer 的 validate() 函数的 user_queryset,但是我仍然收到此错误: assert value is not None,
我正在尝试从破解编码面试中回答以下问题。下面的代码是 GitHub 上一个项目的一部分,here . Given a binary search tree, design an algorithm w
我正在使用 IBM Bluemix 为学校项目创建 Web 服务。 我设置了本地主机来运行我的代码,但是当我在 Windows 10 命令提示符中键入“npm start”时,我遇到了“assert.
将 tf.Dataset 传递到 tf.Keras 模型的 fit() 时,我收到 AssertionError方法。 我正在使用tensorflow==2.0.0。 我检查了我的数据集是否有效: #
我有一个异步回调,我为此编写了一个 junit 测试用例。我正在遵循 CountDownLatch 方法。如果回调失败,我必须使测试用例失败。这是我的代码 lock = new CountDo
我是一名优秀的程序员,十分优秀!