2011-06-29 14 views
0

他のスレッドからアクセスされるオブジェクトのArrayListを持つAndroidで外部ライブラリを使用しています。私の問題は、他のスレッドでnull例外を発生させないように、このAarrayListからいくつかのオブジェクトを移動したいということです。ArrayListスレッドセーフでオブジェクトを移動する最善の方法は何ですか?

私はArrayList ABCDEFGHを持っています.Fを実際の位置から最初の位置に移動したいので、ArrayListはFABCDEGHになります。他のすべてのオブジェクトが右にシフトされているので、私はそれにスワップを使用することはできません。

素朴な実装は次のとおりです。

list.remove(F); 
list.add(0,F); 

しかし、他のスレッドで、この実装の原因はnull例外他のスレッドが手書きカウントループでリストをループしているので、その競合状態のため糸ループ私は外部ライブラリにアクセスすることができないので、ArrayListトレッドを安全にすることはできません。

競技条件なしで(Arraylistの任意の位置から任意の位置へ)この動きをするより良い方法はありますか? ArrayListのサイズは変更されないことに注意してください。

+0

あなたはループと削除/追加を行うコードを所有していますか?または、ループはライブラリコードで実行されますか? – sudocode

+0

ループはライブラリコード – Akira

答えて

3

ループとスワップコードを所有している場合は、両方の操作をリストに同期させることができます。

// code for loop 
for (int i = 0; i < length; i++) { 
    synchronized(list) { 
    letter = list.get(i); 
    } 
    // whatever else 
} 

// code for swap 
synchronized(list) { 
    list.remove(F); 
    list.add(0,F); 
} 

更新

私はあなたがあなたのスワップ/ループコードで行った変更を確認するために、ループのスレッドを必要とすることを想定しています。あれは正しいですか?

もしそうでなければ、あなたはあなた自身のために単にリストを複製/コピーすることができます。

List copy = new ArrayList(list); 
copy.remove(F); 
copy.add(0,F); 
+0

で実行されます。私はループコードを所有していません。スワップ(スワップではなくムーブ)のみです。スワップだけを同期させると、まだ競合状態になりますか?ありがとう – Akira

+0

ループコードを所有しておらず、リスト上で同期しない場合は、自分のスレッド上でリストを安全に変更することはできません。 – sudocode

0

のArrayList内のオブジェクトの順序を変更するが、add()remove()またはサイズを変更することができる任意の他の方法を使用しません。

Object temp = F; 

for (int i = list.indexOf(F); i > 0; i--) { 
    list.set(i, list.get(i - 1)); 
} 

list.set(0, temp); 

注、しかしながら、他のスレッドのループが間違った順序でオブジェクト、または異なる位置における同じオブジェクトに遭遇することが次のよう

は、それは、むしろinelegantly、行うことができます。そして、他のスレッドがアイテムを追加または削除すると、これは機能しません。

リストを同期できない場合、おそらくあなたのスレッドからそれを修正しようとすべきではないと思います。

関連する問題