2016-04-16 3 views
4

私はHashMapのキータイプとしてJavaでカスタムクラスFooを使用しています。 Fooインスタンスのすべてのフィールドは不変です(これらはfinalとprivateで宣言され、コンストラクタでのみ値が割り当てられます)。したがって、与えられたFooオブジェクトのhashCode()も修正されています。最適化のために、コンストラクタで計算して、hashCode()メソッドでその値を返すだけです。スレッドを使用したJavaの最適化

Fooのインスタンスもvalue()のメソッドを持ち、オブジェクトがインスタンス化されると同様の固定値を返します。現在、コンストラクタで計算して返していますが、hashCode()value()の間に違いがあります。hashCode()は、オブジェクトの作成後ほぼ即時に呼び出されますが、後でvalue()が呼び出されます。私は、ハッシュコードを計算するために別のスレッドを有するという理由だけで、同期の問題の実行時間を増加させることを理解し、しかし:

  • これはvalue()を計算するための良い方法ですか?それは実行時間をまったく改善するでしょうか?
  • は簡単ですThreads、またはプールなどを使用する必要がありますか?

注:私は私のプログラムの間違った部分を最適化してるようこれは見えるかもしれませんが、私はすでに「正しい」部分に働いて、へ〜17秒から下の平均実行時間を持ってきました〜2秒。 編集:これは5000個以上のオブジェクトがありますが、これは控えめな見積もりです。

+0

でチェック例外をラップすることができ、それは 'ことができるだろう)(値'として、奇妙なことでしょう無効な値を返します。 – njzk2

+0

@ njzk2それは私のプログラムには問題ありません。私が言ったように、 'value()'はオブジェクトが作られてから長い時間と呼ばれます。 – shardulc

答えて

2

遅延計算はここでの良いアプローチですが、これらのオブジェクトをたくさん作成すると、スレッドプールが使用できます。

value()の準備が完了するまでの戻り値は、無効な値を返すのを避け、代わりにブロックします(isValueReady()ヘルパーを追加する)か、即座に "未来"を返すようにします同じものを提供しますisReadyとブロック方法get

また、「ずっと後で」に頼ってはいけません。使用する前に必ず値を確認してください。

+0

理論的には、あなたの答えは私には聞こえますが、実際には何かがうまくいかない:プログラムは通常の5倍以上の時間がかかっています。私の状況をより具体的にするために、どのような詳細を提示すればよいですか? – shardulc

+0

@shardulc多くの変数がありますが、私はあなたのアプリケーションを知らない。まず、2つのことを見てみましょう。1. value()の計算量はどれくらいですか?スレッドプールのスレッドを作成するのが重い場合、それは価値がありません。 2. CPUが枯渇してアプリケーションがどのようになっていますか? CPU使用率が100%の場合、計算を延期してもメリットはありません。正直なところ、それはまったく別のものかもしれません...私は、コードから明白でないか、または何かが遅いのをデバッグすることで、プロファイリングに頼っています。 – Oak

1

私はvalueためFutureを作成することはお勧め - 静的fixedTheadPoolsubmitその上value計算を作成。 valueは、それが利用可能になる前にアクセスされるというリスクはありません。この方法で - 最悪の場合には、valueにアクセスされているもの(例えば、デッドロックが懸念される場合やuse the version with a timeout)ができる

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); 
     } 
    } 
} 
関連する問題