在java中实现不透明句柄

时间:2013-02-15 10:41:29

标签: java handle

我想在java中实现一个不透明的句柄。

即。当用户在我的工厂类上调用Create时,我创建了一个类的对象,但是不返回对象本身,而是返回一个表示该类实例的int。我将有一个HashMap,它将int作为键存储,对象作为值存储。 该类的每个其他方法都将int作为一个参数&它将从HashMap中检索对象,并对相应的对象执行所需的操作。 将有一个删除方法,它将从HashMap中删除它并允许它被垃圾收集。

我想知道是否有任何现有的类/数据结构可以避免我必须实现代码的句柄部分?

我认为我不能使用hashCodeidentityHashCode作为唯一标识符,因为它们不能保证是唯一的。

如果我自己实现一个运行计数器,我将不得不在创建唯一ID时处理线程安全等问题,当我从hashMap中删除对象时重用id。所以我想知道是否有任何可以帮助解决此问题的现有课程。

4 个答案:

答案 0 :(得分:1)

我会保留自己的柜台。如果您担心线程安全,请使用AtomicInteger

我不会尝试重用id:这将使调试和日志记录变得非常困难。 你不太可能用完整数。

答案 1 :(得分:1)

将长值作为id。你永远不会用完多头。重新使用int会带来更高的复杂性和减慢速度 使用同步(或私有锁对象)编写get()set()和increment()很简单。否则请将AtomicLongincrementAndGet()

一起使用

答案 2 :(得分:1)

让我们做简单的计算。你说你将拥有最多10000个对象,最多1小时的实时时间。让我们假设更艰苦的条件 - 每1分钟10000个物体。 32位整数足够大约1年。此外,即使整数溢出,它也将从零开始,重用1年前使用的整数。我认为这已经足够了。因此,只需使用AtomicInteger,它的工作速度非常快,足以满足您的要求。

如果你仍然有疑问,你可以有一个更有弹性的解决方案 - 当生成一个新句柄时,首先检查HashMap是否已经有这个键(它是非常快的操作),如果确实有,只需选择下一个整数。它与操作系统中的https://superuser.com/questions/135007/how-are-pids-generated类似。

答案 3 :(得分:0)

我建议你使用基本的OO设计来返回一个封装的对象 - 它简单,强大且众所周知。

不要从工厂返回int并将其传递给工厂方法。相反,为新创建的对象(抽象数据类型)声明一个特定的类,并返回此ADT类的实例。将对象上运行的方法从工厂移动到ADT类。

E.g。

// file Widget.java
package com.company.widgets;

public class Widget {
    String widgetName;
    String widgetType;
    int widgetCode;

    // By making the constructor "protected", can stop arbitrary classes from 
    // constructing and ensure on the WidgetFactory can construct
    protected Widget(String widgetName,
                    String widgetType,
                    int widgetCode) {
         this.widgetName = widgetName;
         this.widgetType = widgetType;
         this.widgetCode = widgetCode;
    }

    public boolean equals(Object other) {
         ...
    }

    public int hashcode() {
         ...
    }

    public void widgetOperation1(String fred) {
        ...
    }

    public String widgetOperation2(int barney ) {
        ...
    }
}

//========================================================

// file WidgetFactory.java
package com.company.widgets;

public class WidgetFactory {
    // Member attributes as needed. E.g. static Set of created Widget objects
    private static Set<Widget> widgetSet;
    static { widgetSet = new HashSet() }

    // 
    public static Widget createNewWidget() {
        Widget widget = new Widget();
        widgetSet.add(widget);
        return widget;
    }

    public static removeWidget(Widget widget) {
        widgetSet.remove(Widget)
    }
}

请注意,1000个对象并不多,因此该解决方案将具有高性能。如果你真的需要优化每微秒的性能,你可以选择让工厂变得更聪明,这样就不会删除Widgets,而是回收 - 例如你可以有两个集合,widgetsInUseSet和widgetsRecycledSet。