我在Java中使用一个自定义类Foo作为HashMap中的键类型。Foo实例的所有字段都是不可变的(它们被声明为最终的和私有的,并且只在构造函数中被赋值)。因此,给定Foo对象的Foo也是固定的,为了优化目的,我在构造函数中计算它,并在hashCode()方法中返回该值。
Foo的实例还具有一个value()方法,该方法在对象实例化后返回类似的固定值。目前,我还在构造函数中计算它,并在方法中返回它,但是hashCode()和value()之间有一个区别:在创建对象之后,hashCode()几乎是第一次被调用,但是value()被调用得更晚。我理解使用单独的线程来计算哈希代码只会因为同步问题而增加运行时,但是:
value()的好方法吗?它会改善运行时间吗?Threads是否足够,或者我是否需要使用池等?注意:这似乎是我在优化程序中的错误部分,但我已经完成了“正确”部分的工作,并将平均运行时间从17秒降到了2秒。编辑:将有超过5000个Foo对象,这是一个保守的估计。
发布于 2016-04-16 17:03:48
听起来,延迟计算无疑是一种很好的方法--是的,如果您创建了很多这样的对象,那么线程池就是最好的选择。
至于value()的返回值,直到它准备好为止,我将避免返回无效的值,而不是让它阻塞(并添加一些isValueReady()助手),或者使它立即返回一个“未来”--一些提供相同isReady和阻塞get方法的对象。
而且,永远不要依赖“很晚”--在使用它之前,一定要确保它的价值已经就绪。
发布于 2016-04-16 20:46:48
我建议为value创建一个value--创建一个静态fixedTheadPool,并对其进行value计算。这样就不会有value在可用之前被访问的风险--最糟糕的情况是,任何访问value的东西都会阻塞Future.get调用(或使用带有超时的版本 )
因为Future.get抛出检查过的异常(这可能会带来麻烦),所以可以在类的getter方法中包装get调用,并将检查的异常包装在RuntimeException中。
class MyClass {
private static final ExecutorService executor = Executors.newFixedThreadPool(/* some value that makes sense */);
private final Future<Value> future;
public MyClass() {
future = executor.submit(/* Callable */);
}
public boolean isValueDone() {
return future.isDone();
}
public Value value() {
try {
return future.get();
} catch(InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
}
}https://stackoverflow.com/questions/36666942
复制相似问题