二項係数の配列を維持するためにダブルチェック ロックを使用しようとしていますが、ダブルチェック ロックが機能しないことを最近読みました。効率は非常に重要であるため、条件ステートメント内でのみ使用しない限り、volatile を使用することはできません。シングルトンオブジェクトで静的クラスを使用する方法がわかりません(これはフレームワークの一部であり、関数を使用する必要がある数値の種類がわからないため、最大値を推測できません選択された値は、または関数がまったく使用されるかどうか)。私が考えることができる唯一のことは、すべてを静的ではなく、このメソッドを使用する必要がある各スレッドが独自の配列で Choose オブジェクトをインスタンス化することを主張することです。それは必要ではないようです。
public static final class Util{
/**
* Static array of nCr values
*/
public static long[][] nCr_arr;
/**
* Calculate binomial coefficient (n k)
*
* @param n
* n
* @param k
* k
* @return n choose k
*/
public static long nCr(int n, int k) {
if (k < 0)
throw new ArithmeticException("Cannot choose a negative number");
if (n < 0) {
if (k % 2 == 0)
return nCr(-n + k - 1, k);
else
return -nCr(-n + k - 1, k);
}
if (k > n)
return 0;
if (k > n / 2)
k = n - k;
if (nCr_arr == null) {
synchronized (Util.class) {
if (nCr_arr == null)
nCr_arr = new long[n + 1][];
}
}
if (nCr_arr.length <= n) {
synchronized (Util.class) {
if (nCr_arr.length <= n) {
long[][] newNCR = new long[n + 1][];
System.arraycopy(nCr_arr, 0, newNCR, 0, nCr_arr.length);
nCr_arr = newNCR;
}
}
}
if (nCr_arr[n] == null) {
synchronized (Util.class) {
if (nCr_arr[n] == null)
nCr_arr[n] = new long[k + 1];
}
}
if (nCr_arr[n].length <= k) {
synchronized (Util.class) {
if (nCr_arr[n].length <= k) {
long[] newNCR = new long[k + 1];
System.arraycopy(nCr_arr[n], 0, newNCR, 0,
nCr_arr[n].length);
nCr_arr[n] = newNCR;
}
}
}
if (nCr_arr[n][k] == 0) {
if (k == 0)
nCr_arr[n][k] = 1;
else
nCr_arr[n][k] = nCr(n, k - 1) * (n - (k - 1)) / k;
}
return nCr_arr[n][k];
}
}