你真的不想同步Integer
,因为你无法控制哪些实例是相同的,哪些实例是不同的.Java只是不提供这样的工具(除非你在小范围内使用整数),这些工具可以在不同的JVM之间可靠.如果你真的必须在整数上进行同步,那么你需要保留一个Map或整数集,以便保证你得到你想要的确切实例.
更好的方法是创建一个新对象,可能存储在HashMap
由其键入的Integer
同步中.像这样的东西:
public Page getPage(Integer id) { Page p = cache.get(id); if (p == null) { synchronized (getCacheSyncObject(id)) { p = getFromDataBase(id); cache.store(p); } } } private ConcurrentMaplocks = new ConcurrentHashMap (); private Object getCacheSyncObject(final Integer id) { locks.putIfAbsent(id, id); return locks.get(id); }
为了解释这个代码,它使用了ConcurrentMap
允许使用的代码putIfAbsent
.你可以这样做:
locks.putIfAbsent(id, new Object());
但是你会因为每次访问而产生(小)成本.为了避免这种情况,我只是将整数本身保存在Map
.这实现了什么?为什么这与使用Integer本身有什么不同?
get()
从a 执行a 时Map
,会将键与之进行比较equals()
(或者至少使用的方法相当于使用equals()
).具有相同值的两个不同的Integer实例将彼此相等.因此,您可以将任意数量的不同Integer实例new Integer(5)
作为参数传递给,getCacheSyncObject
并且您将始终只返回包含该值的第一个实例.
有些原因可能导致您不希望同步Integer
...如果多个线程在Integer
对象上进行同步,并且因此在他们想要使用不同的锁时无意中使用相同的锁,则可能会陷入死锁.您可以使用以下方法来解决此风险
locks.putIfAbsent(id, new Object());
版本,因此每次访问缓存都会产生(非常)小的成本.这样做,您可以保证此类将在其他类不同步的对象上进行同步.总是一件好事.
你真的不想同步Integer
,因为你无法控制哪些实例是相同的,哪些实例是不同的.Java只是不提供这样的工具(除非你在小范围内使用整数),这些工具可以在不同的JVM之间可靠.如果你真的必须在整数上进行同步,那么你需要保留一个Map或整数集,以便保证你得到你想要的确切实例.
更好的方法是创建一个新对象,可能存储在HashMap
由其键入的Integer
同步中.像这样的东西:
public Page getPage(Integer id) { Page p = cache.get(id); if (p == null) { synchronized (getCacheSyncObject(id)) { p = getFromDataBase(id); cache.store(p); } } } private ConcurrentMaplocks = new ConcurrentHashMap (); private Object getCacheSyncObject(final Integer id) { locks.putIfAbsent(id, id); return locks.get(id); }
为了解释这个代码,它使用了ConcurrentMap
允许使用的代码putIfAbsent
.你可以这样做:
locks.putIfAbsent(id, new Object());
但是你会因为每次访问而产生(小)成本.为了避免这种情况,我只是将整数本身保存在Map
.这实现了什么?为什么这与使用Integer本身有什么不同?
get()
从a 执行a 时Map
,会将键与之进行比较equals()
(或者至少使用的方法相当于使用equals()
).具有相同值的两个不同的Integer实例将彼此相等.因此,您可以将任意数量的不同Integer实例new Integer(5)
作为参数传递给,getCacheSyncObject
并且您将始终只返回包含该值的第一个实例.
有些原因可能导致您不希望同步Integer
...如果多个线程在Integer
对象上进行同步,并且因此在他们想要使用不同的锁时无意中使用相同的锁,则可能会陷入死锁.您可以使用以下方法来解决此风险
locks.putIfAbsent(id, new Object());
版本,因此每次访问缓存都会产生(非常)小的成本.这样做,您可以保证此类将在其他类不同步的对象上进行同步.总是一件好事.