Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中实现不透明句柄_Java_Handle - Fatal编程技术网

在java中实现不透明句柄

在java中实现不透明句柄,java,handle,Java,Handle,我想用java实现一个不透明句柄 i、 当用户在我的工厂类上调用Create时,我创建了该类的一个对象,但不返回对象本身,而是返回一个表示该类实例的int。我将有一个HashMap,它将int存储为键,对象存储为值。 该类的每个其他方法都将int作为一个参数&它将从HashMap中检索对象,并对相应的对象执行所需的操作。 将有一个remove方法,该方法将它从HashMap中删除,并允许对其进行垃圾收集 我想知道是否有任何现有的类/数据结构可以避免我必须实现代码的句柄部分 我认为我不能使用has

我想用java实现一个不透明句柄

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

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

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


如果我自己实现一个正在运行的计数器,我将不得不处理一些问题,如创建唯一Id时的线程安全,从
hashMap
中删除对象时重用Id等。因此我想知道是否有任何现有类可以帮到这一点。

我将保留自己的计数器。如果您担心线程安全,请使用

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

将long值作为id。long值永远不会用完。重复使用int会导致更高的复杂性和速度减慢。

使用syncronized(或私有锁对象)编写get()set()和increment()非常简单。否则,将
AtomicLong
incrementAndGet()一起使用
。你说过你最多有10000个对象,最多1小时的直播时间。让我们假设更困难的条件-每1分钟10000个对象。32位整数将足够使用大约1年。此外,即使整数溢出,它也将再次从零开始,重用1年前使用的整数。在我看来,这已经足够了。所以,只需使用AtomicInteger,它运行速度非常快,足以满足您的需求


如果您仍然有疑问,您可以有一个更具弹性的解决方案-当生成一个新句柄时,首先检查HashMap是否已经有这个键(这是一个非常快速的操作),如果确实有,只需选择下一个整数。它与操作系统中的类似。

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

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

例如

//文件Widget.java
包com.company.widgets;
公共类小部件{
字符串widgetName;
字符串widgetType;
int-widgetCode;
//通过使构造函数“受保护”,可以阻止任意类从
//在WidgetFactory上构建并确保可以构建
受保护的小部件(字符串widgetName,
字符串widgetType,
整数(widgetCode){
this.widgetName=widgetName;
this.widgetType=widgetType;
this.widgetCode=widgetCode;
}
公共布尔等于(对象其他){
...
}
公共int hashcode(){
...
}
公共无效widgetOperation1(字符串){
...
}
公共字符串widgetOperation2(int-barney){
...
}
}
//========================================================
//文件WidgetFactory.java
包com.company.widgets;
公共类WidgetFactory{
//所需的成员属性。例如,创建的小部件对象的静态集
私有静态集widgetSet;
静态{widgetSet=newhashset()}
// 
公共静态小部件createNewWidget(){
Widget Widget=newwidget();
添加(小部件);
返回控件;
}
公共静态removeWidget(小部件){
widgetSet.remove(小部件)
}
}

请注意,1000个对象并不多,因此此解决方案将非常有效。如果您真的需要优化每微秒的性能,您可以选择使工厂更智能,这样小部件就不会被删除,而是可以循环使用-例如,您可以有两个集合,widgetsInUseSet和widgetsRecycledSet。

手柄是否必须是
int
?如果改用某种句柄类,则可以维护类型安全性。不幸的是,是-它必须是int:-(我可以问一下为什么句柄必须是int吗?另一个问题是,您在地图中一次需要多少个对象,这些对象的寿命有多长?我问这个问题是因为您似乎害怕AtomicInteger解决方案…@AtomicInteger使我的一个问题更简单-同步问题。我使用它没有问题。没有解决问题“回收移除的句柄问题”。任何时候的对象总数可能会达到5000-10000的峰值。对象最多可以生存一个小时左右。但是,我不想让东西打破上述假设。与其说“句柄必须是int”,不如说“句柄不能是类对象”-它必须是be基本类型(int、long等)。这将是一个运行时间很长的应用程序-因此我最终会用完整数。这就是我想知道是否有任何现有的实现将负责回收对象本身已被垃圾收集的ID的原因之一。正如我在本页多次提到的,我知道实现这个用一个对象而不是一个整型。但不幸的是,有一些原因我不能-这不是因为性能原因。原因是什么?我真的很想知道。我已经通读了,你呢
// 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)
    }
}