2016-04-27 6 views
1

Atomic(Double|Integer|Long|Reference)Arrayをクリーンで効率的に成長させる方法はありますか?私の特別なケースでは、コピー中の同時書き込みはありません。新しいものを作成して、ループ内の宛先アレイにソース配列をコピーするための1つの明らかな方法:このコードを原子配列を効率的に成長させる

Atomic*Array dest = new Atomic*Array(newSize); 
for (int i = 0, len = src.length(); i < len; ++i) 
    dest.set(i, src.get(i)); 

はおそらくSystem.arraycopyまたはArrays.copyタイプの機能よりもはるかに遅いとも少し冗長です。

私は交互に、ソースの arrayフィールドを取得し、それを拡張し、アトミック*のArrayコンストラクタに新しい配列を渡すためにリフレクションを使用することができ

try { 
    Field arrayField = Atomic*Array.class.getDeclaredField("array"); 
    arrayField.setAccessible(true); 
    ArrayType srcArray = (ArrayType)arrayField.get(src); 
    Atomic*Array dest = new Atomic*Array(Arrays.copyOf(srcArray, newLength)); 
} catch (IllegalAccessException | NoSuchFieldException e) { 
    throw new AssertionError(e); 
} 

しかし、このコードはあまりにも問題がある:それは実装に依存Atomic*Arrayクラスの2つのコピーを作成します.1つはArrays.copyに、もう1つはdestのコンストラクタにあり、非常に醜いです。

これを行うにはより速く/よりクリーンな方法がありますか?

+0

関連:http://stackoverflow.com/questions/9408112/get-the-array-from-an-atomiclongarray –

+0

消費者が横断できるように古い配列から新しい配列にリンクすることによって、成長することができます。このアイデアの例については、JCToolsの[MpscChunkedArrayQueue](https://github.com/JCTools/JCTools/blob/master/jctools-core/src/main/java/org/jctools/queues/MpscChunkedArrayQueue.java)を参照してください。 –

+0

@BenManesはい私はその考えを考えましたが、リンクで配列をラップする必要があるため、メモリの使用量はかなり高くなります。ロジックは、おおよそのテールポインタを維持する必要があるため、少し複雑です。 1つの配列でうまく動作しているように、私はできるだけ多くのパフォーマンスを得たいと考えています。 –

答えて

1

私はあなたを失望させるだろうと心配しています。Atomic*Arrayを一括してコピーする方法はありません。

javadocを見ると、一度に複数の要素を与える方法はありません。 AtomicIntegerArrayコンストラクタに渡すことができる元の配列を使用していなくても、クラスは内部的にコピーを作成します。

AtomicIntegerArrayのソースコードを見ると、反射を使用すると、クラスはarrayフィールドで特別なことをしません。しかし、私はしません。だけでなく、それはusafeですが、反射も避けるためにしようとしているいくつかのパフォーマンスのペナルティを与えるでしょう。

あなたの目標がアレイを拡張することであれば、使用例に応じてLinkedBlockingQueueまたはCopyOnWriteArrayListをチェックしてください。

私はこの問題を数回実行しましたが、最後にAtomic*Arrayのない方法が見つかりました。

+0

ありがとうございます。私の目標は、非常にメモリ効率のよい非ブロッキングの追加専用リストを実装することです。しかし残念なことに、 'LinkedBlockingQueue'と' CopyOnWriteArrayList'のどちらも私のニーズを満たしていません。前者はノードのメモリをあまりにも多く使い、後者は非常に効率が悪いです。実際、標準ライブラリのコレクションは私の要求に合っていません。 –

+0

"non-blocking"の要件を追加していないのは残念ですが、それ以外の場合は古い 'synchronized'を使うこともできます:) – Mifeet

+0

' Collections.synchronizedList(new ArrayList <>()) 'は動作しますが、競合がないため、(ループでコピーすることによって成長しても)大幅に高速になります。 –

関連する問題