- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
The docs假设您不应该锁定基于值的 Java 类的实例,例如 Optional
因为代码
may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class ... indirectly via an appeal to synchronization...
Why should Java's value-based classes not be serialized?断言
Because future JVM implementations might not use object headers and reference pointers for value-based classes, some of the limitations are clear. (E.g. not locking on an identity which the JVM must not uphold. A reference on which is locked could be removed and replaced by another later, which makes releasing the lock pointless and will cause deadlocks).
即该禁令是面向 future 的。但该断言没有引用资料。
如果面向 future 是基础,我想要一个引用。如果不是,我想了解基础是什么,因为基于值的对象是 Object
。
编辑
顺便说一句,我理解不锁定整数和其他原始包装类的原因;它们可能被缓存。但是我找不到任何文档说基于值的类也是如此,而 Integer 等。基于值(value)观,他们are not value-based classes . IE。 JavaDocs of Optional &ETC。明确地说
This is a value-based class
Integer 则不同。 , &等等
最佳答案
这是 Nicolai Parlog 的博文关于基于值的类:
In Java 8 value types are preceded by value-based classes. Their precise relation in the future is unclear but it could be similar to that of boxed and unboxed primitives (e.g. Integer and int). Additionally, the compiler will likely be free to silently switch between the two to improve performance. Exactly that switching back and forth, i.e. removing and later recreating a reference, also forbids identity-based mechanisms to be applied to value-based classes.
Nicolai 的意思是这样的:
在未来,编译器可能以不保留对象身份的方式在值和基于值的类之间透明地转换。
某些事物(“基于身份的机制”)取决于对象身份。示例包括用于引用的 ==
语义、身份哈希码、原始锁定和对象序列化。
对于那些事情,透明翻译有可能不透明。
在原始锁定的情况下,担心的是可能会发生类似以下序列的事情。
如果两个线程然后使用“实例”作为原始锁,它们可能不知道实际上实际上有两个对象(现在)。如果他们随后尝试同步
,他们将(可能)锁定不同的对象。这意味着无论锁定旨在保护的状态是什么,都不存在互斥。
如果您不锁定基于值的类,您将不必担心这种潜在的危险......在未来。
但请注意,Nicolai 的博文是一个人对 Java 10 或更高版本中可能发生的事情的猜测。
BTW, I understand the reasons not to lock on Integers and other primitive-wrapper classes; they may be cached.
缓存本身不是问题,而是导致问题的机制。真正的问题是很难推断锁定对象的对象标识,因此锁定机制是否合理。
对于原始包装器,装箱和拆箱的语义导致了对象身份的不确定性。展望 future ,提出的值类型 <-> 对象转换将是这种不确定性的另一个来源。
以上博客基于"State of the Values" April 2014. John Rose, Brian Goetz, and Guy Steele其中讨论了将值类型添加到 Java 的 future 版本中。本说明是一个立场声明,而不是一个完全规范(和采纳)的提案。然而,该注释确实给了我们这个提示:
"Many of the above restrictions correspond to the restrictions on so-called value-based classes. In fact, it seems likely that the boxed form of every value type will be a value-based class."
这可以理解为暗示值类型和现有的基于值的类之间存在关系。 (特别是如果您阅读了 value-based classes 的 Java 8 描述的字里行间。)
更新 - 2019/05/18
值类型没有进入 Java 12,它们(还)不在 Java 13 的列表中。
但是,已经可以证明与博文所讨论的问题相关的问题:
public class BrokenSync {
private final Integer lock = 1;
public void someMethod() {
synchronized (lock) {
// do something
}
}
}
问题是 BrokenSync
的每个实例都会通过自动装箱 1
创建一个 Integer
实例。但是 JLS 表示,自动装箱生成的 Integer
对象不一定是不同的对象。因此,您可以使用相同的 Integer
对象作为锁,从而得到 BrokenSync
的所有实例。
关于java - 为什么不锁定一个基于值(value)的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34049186/
我对 Java 并发性比较陌生(还没有阅读 JCIP,但它在我的列表中!)并且我有一个关于锁定行为的问题。具体来说,Java 是锁定对象的引用,还是锁定对象本身? 代码示例(不是 sscce,因为我不
我的团队使用 TortoiseSVN 编写版本控制代码。有时,有人使用“获取锁定”选项。是否有可能看到解决方案中的锁? 最佳答案 http://tortoisesvn.net/docs/nightly
我在使用 SVN 时遇到了一个小问题。 当我跑 svn stat我明白了: ~ some/dir 当我跑 svn commit -m "test"我明白了:svn: working copy
我启用了 jenkins 安全性,认为它会提示我创建一个帐户。我尝试在 c:/program files/jenkins 中删除和编辑我的 config.xml 文件,但我不确定如何在没有访问权限的情
实现与 S3 结合使用的简单锁定机制的推荐方法是什么? 我想做的例子: 通过对象 ID 获取锁 从 S3 读取对象 修改数据 将对象写入 S3 释放锁 理想情况下寻找基于云的锁定机制。我可以在本地使用
找到这个here : 一般来说,在以下任何情况下,请考虑在列上创建索引: 索引列上存在引用完整性约束,或者列。索引是避免全表锁的一种方法,否则,如果您更新父表主键,则需要,合并到父表中,或从父表中删除
在我的程序中,我将把每个“ block ”数据存储在一个单独的文件中。多个线程都会读取和写入各种文件,我想避免因未正确同步而可能出现的问题。本质上,我想要一个设置,其中每个文件的行为就好像它有自己的
我想使用此script作为资源,通过使用Windows API(重置管理器)与Go for Windows中的内容相同 到目前为止,我的代码是 Rstrtmgr := syscall.NewLazyD
这里的问题是:“这些选择中的哪一个对于线程安全选择的剧院具有最佳性能?” public static List lockList = initializeLocks(); public boolean
我有一个侧面菜单,单击图标时打开,单击页面或单击菜单上的项目时关闭。我正在尝试实现锁定,因此当单击锁定图标时,即使您单击菜单项或页面,菜单也不会关闭。 我能够将图标从锁定图标更改为解锁图标,但我在停止
使用 TRueType 字体编写 SDL 程序。我调用 TTF_Init() 来初始化 TTF 并使用 TTF_OpenFont( name, size ) 打开我的字体。 我有一个例程,可以使用以下
我正在尝试调试基于运行 FreeRTOS 的 STM32F3 uC 的应用程序。我已在应用程序的线程上下文中的随机位置手动将 PSP 设置为无效值(例如 0),希望触发 memManageFault/
我有以下 C# 代码: 1. List bandEdgeList; 2. 3. bandEdgeList = CicApplication.BandEdgeCache.Where(r
我正在用骰子制作游戏。这个想法是持有/锁定骰子。我把骰子做成按钮,这样现在就可以点击它们了。示例:我抛出一个“6”和一个“1”。我点击“6”,所以现在只会抛出“1”。 我对这个有点迷失了,我需要创建
我正在使用以下代码下载约 200mb 的播客并将其写入文档目录: var podcastRequest = NSURLRequest(URL: audioUrl) NSURLConnection.se
下面的类 DoStuff 启动一个线程并同步以保护监听器对象在 null 时不被访问。 现在,当从外部访问 DoStuff 类函数 setOnProgressListener() 时,我遇到了问题,因
我正在编写一个使用巨大背景 Canvas 的网站。我试图锁定浏览器调整大小处理程序以避免滚动问题(背景越界等) 这是我第一次做一个完整的后台网站。任何有关优化的建议(png 大小 580.72 KB
我是 C# 和线程的新手,我有这个问题要解决: 我有一个处理一些数据的线程,它会不时(必要时)触发我在启动线程之前设置的事件方法 (DataProcessor)。该线程位于专有 dll 中。所以我不能
我正在使用相机,我使用的是文档中给出的完全相同的示例: http://developer.android.com/resources/samples/ApiDemos/src/com/example/
我有几个座位可供用户预订。同一时间,只有一个用户可以参与预订过程,这样同一个座位就不会被多个用户预订。在我的 Java 代码中,我使用了“synchronized”关键字来完成它。这行得通。 但是,现
我是一名优秀的程序员,十分优秀!