在java中实现不透明句柄
我想用java实现一个不透明句柄
也就是说,当用户对我的工厂类调用Create时,我创建了该类的一个对象,但不返回对象本身,而是返回一个表示该类实例的int。我将有一个HashMap
,它将int存储为键,对象存储为值。
该类的其他每个方法都将int作为一个参数&;它将从HashMap
中检索对象,并对相应的对象执行所需的操作。
将有一个remove方法将它从HashMap
中删除,并允许对其进行垃圾收集
我想知道是否有任何现有的类/数据结构可以避免我必须实现代码的句柄部分
我认为我不能使用hashCode
或identityHashCode
作为唯一标识符,因为它们不能保证是唯一的
如果我自己实现一个正在运行的计数器,我将不得不在创建唯一Id时处理线程安全问题,在从hashMap
中删除对象时重用Id等问题。因此我想知道是否有任何现有类可以对此有所帮助
# 1 楼答案
以long值作为id。long值永远不会用完。重复使用int会导致更高的复杂性和速度减慢
使用syncronized(或私有锁对象)编写get()set()和increment()很简单。否则使用
AtomicLong
和incrementAndGet()
# 2 楼答案
我建议您使用基本的OO设计,它返回一个封装的对象——它简单、强大且众所周知
不要从工厂返回int并将其传递给工厂方法。相反,为新创建的对象(抽象数据类型)声明一个特定的类,并返回这个ADT类的实例。将操作对象的方法从工厂移动到ADT类
例如
请注意,1000个对象并不多,因此此解决方案将非常有效。如果你真的需要优化每微秒的性能,你可以选择让工厂变得更智能,这样小部件就不会被删除,而是可以循环使用——例如,你可以有两套,widgetsInUseSet和widgetsRecycledSet
# 3 楼答案
让我们做简单的计算。你说过你最多有10000个对象,最多1小时的直播时间。让我们假设更严酷的条件——每1分钟10000个物体。32位整数将足够使用大约1年。此外,即使整数溢出,它也会再次从零开始,重用1年前使用的整数。在我看来,这已经足够了。所以,只需使用AtomicInteger,它运行速度非常快,足以满足您的需求
如果你仍然有疑问,你可以有一个更具弹性的解决方案——当生成一个新句柄时,首先检查HashMap是否已经有这个键(这是一个非常快速的操作),如果确实有,只需选择下一个整数。它与操作系统中的https://superuser.com/questions/135007/how-are-pids-generated类似
# 4 楼答案
我会保留自己的柜台。如果担心线程安全,请使用AtomicInteger
我也不会尝试重复使用ID:这将使调试和记录变得非常困难。 整数不太可能用完