- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在学习this了解新 JMM 中最终字段的行为(从 5 开始)。这个概念很明确:在正确构造对象后,保证初始化的 final 字段对所有线程的可见性。
但是在本节的末尾,我读到了这个,这让我很困惑:
Now, having said all of this, if, after a thread constructs an immutable object (that is, an object that only contains final fields), you want to ensure that it is seen correctly by all of the other thread, you still typically need to use synchronization. There is no other way to ensure, for example, that the reference to the immutable object will be seen by the second thread.
这是否意味着尽管各个最终字段(构成不可变对象(immutable对象))没有同步(例如,此处可见性)问题。但是在一个线程中首次创建的不可变对象(immutable对象)本身在其他线程中可能不可见(正确创建)?
如果是这样,虽然我们可以跨线程共享初始化的不可变对象(immutable对象)而无需担心线程不安全,但在创建时,它们需要像其他可变对象一样“特别注意”线程安全?
最佳答案
final 字段的语义,定义在 section 17.5 of the JLS 中, 保证:
A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
换句话说,它表示如果一个线程看到一个完全初始化的对象,那么它保证能正确看到它的最终字段初始化。
但是,不能保证对象对给定线程可见。这是一个不同的问题。
如果您不使用某种同步来发布对象的引用,那么其他线程可能永远无法看到对它的引用。
考虑以下代码:
final class A {
private final int x;
A(int x) { this.x = x; }
public getX() { return x; }
}
class Main {
static volatile A a1 = null;
static A a2 = null;
public static void main(String[] args) {
new Thread(new Runnable() { void run() { try {
while (a1 == null) Thread.sleep(50);
System.out.println(a1.getX()); } catch (Throwable t) {}
}}).start()
new Thread(new Runnable() { void run() { try {
while (a2 == null) Thread.sleep(50);
System.out.println(a2.getX()); } catch (Throwable t) {}
}}).start()
a1 = new A(1); a2 = new A(1);
}
}
请注意,a1
字段是可变的。这确保了,最终,对该字段的写入将在一段时间后对所有读取它的线程可见。 a2
字段不是 volatile 的(因此,一个线程对该字段的写入可能永远不会被其他线程注意到)。
在这段代码中,我们可以确定线程 1 将完成执行(也就是说,它将看到 a1 != null
。但是,线程 2 可能会停止,因为它永远不会看到对字段 a2
的写入,因为它不是 volatile 的。
关于java - 同步以确保对不可变对象(immutable对象)的引用将被另一个线程看到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6599058/
我有以下对象: dog = { location: { x: 52.1089, y: 16.2323 }, f: function(message) { alert
在 TSQL 中,如果我要搜索有效的 .com 电子邮件地址,我需要确保有一个 @ 符号,它以 .com 结尾,并且在 @ 前后至少有一个字符。 SELECT * FROM CUSTOMER WHER
我正在尝试准备一个信用卡交易列表,以便在 Excel 2010 中进行透视和进一步分析(满足个人需求)。问题是我的银行机构没有遵循标准的日期格式,所以有时日期会显示为 Jun. 1, 2013 , 有
看来您不能在 riak 中进行交易。如何确保数据正确? 假设我们要插入评论。在 redis 我会做 commentId=incr commentCount multi SET comment_post
对于下面给定的模式,是否可以确保至少一个属性包含一个值(即 minLength 为 1): { "$schema": "http://json-schema.org/draft-04/sche
我计划在 Haxe 的一个子集中编写 Haxe 库,这些库将编译为每种 Haxe 目标语言。有什么方法可以验证 Haxe 程序是否可以编译为所有目标语言,是否可以在不手动测试每个目标平台上的编译代码的
如果浏览器窗口未聚焦,则当前页面上的所有 webdriver 标识都失败。 如何使用 webdriver 使浏览器成为焦点? 最佳答案 ((JavascriptExecutor) webDriver)
我从这样的 HTML GET 请求中获取图像链接... www.example.com?image=www.anotherdomain.com/image.jpg if (isset($_GET['i
我有一个 eunit 测试,它生成一个唯一的节点名称并开始分发: {A,B,C} = now(), Nodename = list_to_atom(lists:flatten(io_lib:forma
我正在完成我的 iPhone 应用程序。我只是担心我们的网络服务器级别的安全性。数据通过网络服务被传送到 iPhone 应用程序。 我可以在网络服务上采取哪些安全措施,以免受到攻击? 谢谢 最佳答案
我正在编写一个应用程序,该应用程序启动一个运行简单 Web 服务器的子进程。我正在使用 NSTask 并通过管道与其进行通信,一切看起来或多或少都很好。但是,如果我的程序崩溃,子进程将保持事件状态,并
我有一些应用程序,我调用 ShowMessage('Complete!');在长时间操作结束时。 大多数时候,这效果很好,但每隔一段时间,消息对话框就会显示在主窗体后面。 有什么方法可以确保 Show
我通过将消息插入集合并让模板使用 {{#each}} 打印出集合来创建一个简单的聊天。 我不太熟悉安全性,但是有没有办法让它符合 EFF 规定? https://www.eff.org/secure-
我有一个商店,我想在其中正确管理 id。假设我有以下帖子存储: type Post = { id: number; title: string; body?: string; } type
我有一个使用 ajax post 方法和数据表的程序。经过几周的摆弄,我确定我根本不明白 javascript 是如何工作的。这是我的 JavaScript: $('#SaveTimeSheet').
我有一个系统,如果从 Azure 服务总线丢失消息将是一场灾难,也就是说,数据将永远丢失,并且没有实际方法可以在不造成重大中断的情况下修复损坏。 在这种情况下我可以完全依赖 ASB 吗? (即使它
如何确保 scalatest 测试不会并行运行?在 0.12 之前,我有一个 sbt 设置: parallelExecution in Test := false 新版本引入了一些复杂的机制。这种更简
我的端点有两个如下所示的 promise : request.post({ url: url, json: smsSTART, header
简短版本 当 ui-router 转换到新 View 时(以我不完全理解的方式使用 ngAnimate),它会添加类 ng-leave 和 ng-leave-active 到当前 View 。它还将类
目前正在努力寻找验证 2 个表的方法(有效地验证表 A 的大量行) 我有两张 table 表A ID A B C 表格匹配 ID Number A 1 A 2 A 9 B 1
我是一名优秀的程序员,十分优秀!