2016-07-05 34 views
0

私はStats計算に使用するUtilクラスを持っています。指数移動平均は複数のスレッド間で計算されます。また、このスレッドはdifferents値を倍にし、もう一方をlongに渡します。私はジェネリック医薬品を作りたいと思っており、に同期させてメソッドのシグネチャに適用していることを確認してください。スレッドセーフと静的クラスのジェネリック

public class StatUtils { 

    public static class WMA { 
     // MMA 
    } 
    public static class EMA { 

     /** The alpha. */ 
     private static double staticAlpha = 0.9; 

     /** The old value. */ 
     private static double staticOldValue = 1.0; 

     /** 
     * Compute. 
     * 
     * @param pValue the value 
     * @return the double 
     */ 
     public static synchronized double compute(double pValue) { 
      if (staticOldValue == 0.0) { 
       staticOldValue = pValue; 
       return pValue; 
      } 
      double lValue = staticOldValue + staticAlpha * (pValue - staticOldValue); 
      staticOldValue = lValue; 
      return lValue; 
     } 
    } 
} 

computeメソッドのスレッドは安全ですか?この静的なクラスを一般的にすることが可能な場合は?

+0

問題は、あなたのクラスの設計であると思われます。なぜ静的なクラスメンバ 'staticAlpha'をコンストラクタからインスタンス化したいのですか?私は正確な要件についてはわかりませんが、あなたのコードを見れば、適切に設計されていれば、同期が必要ないと思います。 –

+0

私はクラスをインスタンス化しないエラーだったことに注意してください。 –

+0

どの部分が一般的になるべきですか? double型ではなくジェネリック型を使用する場合、 '計算'するべきことは何ですか? –

答えて

1

あなたのメソッドはスレッドセーフですが、ジェネリックを静的クラスにすることはできません。ジェネリック型は、クラスがインスタンス化されるときに解決されますが、これは静的クラスでは発生しません。

次のような一般的なメソッドを定義することができます。

public static synchronized <T extends Number> compute(T pValue) 

しかし、長い値は問題なく倍増するキャストすることができますので、あなたのケースでは、単に二重を使用することができます。

+0

しかし、その逆は精度の損失を伴います。時間の場合、それは非常に貴重です。 –

+1

しかし、あなたはダブルからキャストにキャストする必要はありません。ダブルを使用して結果を保存してください。例えば、(ロング)9223372036854775807のタイムスタンプは(ダブル)9.223372036854776E18として保存されます。必要に応じて、科学的表記なしで印刷することもできます。http://stackoverflow.com/questions/16098046/how-to-print-double-value-without-scientific-notation-using-javaもちろん、19桁の長い数字で作業する場合は、長めから2桁にキャストすると4桁の有効数字が失われます。 –

1

はい、現在のアプローチはスレッドセーフです。しかし、全体としてcomputeメソッドが1つのスレッドでブロックされるほど効率的ではないかもしれません。

私はEMAアルゴリズムについてはよく分からないですが、あなたは大丈夫です場合のスレッドがstaticOldValueのほぼ最新の値を使用することを、あなたが好きそれを改善することができます

public static class EMA { 

    /** The alpha. */ 
    private static double staticAlpha = 0.9; 

    /** The old value. */ 
    private static double staticOldValue = 1.0; 

    private static Object monitor = new Object(); 

    /** 
    * Compute. 
    * 
    * @param pValue the value 
    * @return the double 
    */ 
    public static double compute(double pValue) { 
     synchronized (monitor) { 
     if (staticOldValue == 0.0) { 
      staticOldValue = pValue; 
      return pValue; 
     } 
     } 

     double lValue = staticOldValue + staticAlpha * (pValue - staticOldValue); 
     synchronized (monitor) { 
     staticOldValue = lValue; 
     } 

     return lValue; 
    } 
    } 
関連する問題