![]() |
1
9
正在尝试同步
如果允许对象以改变
这个
|
![]() |
2
7
为什么要同步?在这种情况下,重要的是它们在比较过程中是否发生了变化,而取决于相等性的代码在运行之前是否立即发生了变化。(即如果您有依赖于相等性的代码,那么如果在此代码之前或期间值变得不相等,会发生什么情况) 我想你得看看更大的过程,看看你需要锁在哪里。 |
![]() |
3
6
其中,如果在保留同步后不能保证结果为真,则synchronizing equals()中的点是:
因此,只需将对geti()的调用一个接一个地同步,而无需更改输出—这很简单,不再有效。 您必须始终同步整个块:
诚然,您仍将面临同样的问题,但至少您的同步在正确的点;) |
![]() |
4
3
如果说得够多的话,hashcode()、equals()或compareto()使用的字段应该是不可变的,最好是final。在这种情况下,您不需要同步它们。 实现hashcode()的唯一原因是可以将对象添加到哈希集合中,并且不能有效地更改已添加到该集合中的对象的hashcode()。 |
![]() |
5
2
您试图在可变对象上定义基于内容的“equals”和“hashcode”。这不仅不可能,而且毫无意义。根据 http://java.sun.com/javase/6/docs/api/java/lang/Object.html “equals”和“hashcode”都需要一致:对于同一对象上的连续调用,返回相同的值。根据定义,易变性阻止了这一点。这不仅仅是理论:许多其他类(例如集合)依赖于实现equals/hashcode正确语义的对象。 同步问题是个棘手的问题。当您解决底层问题(易变性)时,不需要同步。如果不解决易变性问题,那么再多的同步也帮不了你。 |
![]() |
6
1
(我假设您对这里的一般情况感兴趣,而不仅仅是对包装整数感兴趣。)
不能阻止两个线程调用
因此,当您尝试进行比较时,同步将防止包装值处于不一致状态(例如两个
|
![]() |
7
1
确定同步是否严格必要的唯一方法是分析整个程序的情况。有两件事你需要寻找:一个线程正在改变一个对象,而另一个线程正在调用equals;还有一个线程正在调用
如果你把两个都锁上
这不能保证两个对象具有相同的值
此外,这并不能完全消除僵局的风险。考虑线程可以调用
如果两个线程调用
(不过,你确实需要打电话给
有人说过,基于价值的
|
![]() |
8
1
始终以相同的顺序锁定它们,一种可以确定顺序的方法是
编辑以包含注释: 处理identityhashcodes相等的罕见情况的最佳解决方案需要更多关于这些对象的其他锁的详细信息。 所有多对象锁定要求应使用相同的解析过程。 您可以创建一个共享实用程序来在锁需求的短期内跟踪具有相同标识hashcode的对象,并在跟踪期间为它们提供可重复的顺序。 |
![]() |
9
0
正确实施
|
![]() |
10
0
正如jason day指出的,整数比较已经是原子的了,所以在这里同步是多余的。但如果你只是在构建一个简单的例子,在现实生活中,你想到的是一个更复杂的对象: 对你的问题的直接回答是,确保你总是以一致的顺序比较项目。顺序是什么并不重要,只要是一致的。在这种情况下,system.identifyHashcode将提供如下顺序:
然后声明equalshelper private并让它做真正的比较工作。 (但哇,这是一个很小问题的代码。) 注意,要使其工作,任何可以更改对象状态的函数都必须声明为synchronized。 另一个选项是同步sync.class而不是同步任何一个对象,然后同步sync.class上的任何setter。这将把所有东西都锁定在一个互斥锁上,从而避免整个问题。当然,这取决于您正在执行的操作,可能会导致某些线程被意外阻塞。你必须根据你的程序是关于什么来考虑它的含义。 如果这是您正在处理的项目中的一个实际问题,则需要考虑的另一个重要选择是使对象不可变。想想string和stringbuilder。你可以创建一个syncbuilder对象,它允许你做任何你需要做的工作来创建一个syncbuilder对象,然后有一个syncbuilder对象,它的状态由构造函数设置,并且永远不会改变。创建采用SyncBuilder并将其状态设置为匹配或具有SyncBuilder.ToSync方法的构造函数。无论哪种方式,您都可以在syncbuilder中完成所有构建,然后将其转换为同步,现在您可以保证不变性,这样就完全不必干扰同步。 |
![]() |
11
0
不要使用同步。想想不可改变的豆子。 |
![]() |
12
0
您需要确保对象不会在对hashcode()和equals()的调用(如果调用)之间发生更改。然后,当对象位于hashmap中时,必须确保对象不会发生更改(以扩展hashcode和equals)。要更改对象,必须先将其删除,然后更改并将其放回。 |
![]() |
13
0
正如其他人所提到的,如果在equals检查期间发生了变化,那么已经存在疯狂行为的可能性(即使是正确的同步)。所以,您真正需要担心的是可见性(您需要确保“在”equals调用之前发生的更改是可见的)。因此,您可以只执行“快照”等于,这在“之前发生”关系方面是正确的,并且不会出现锁排序问题:
|
![]() |
14
-2
读取和写入
同样,您不需要同步
|
|
synthax · 具有容差级别的双精度哈希方法 7 年前 |
![]() |
Relaxsingh · 附加导师程序无法正常工作***阅读说明*** 7 年前 |
|
user8589267 · 我的equals方法有什么问题? 7 年前 |
![]() |
James W. · 带有通配符的java黑名单 7 年前 |