2012-01-24 9 views
4

私は多くを検索しましたが、特定の解決策を見つけることができませんでした。また、これに関するstackoverflowに関するいくつかの質問がありますが、私は満足する答えを見つけることができないので、私は再びそれを求めています。javaスレッドに異なるオブジェクトをアクセスする

私はJavaで次のようなクラスを持っています。 私はJavaでスレッドを使う方法を知っています。

//please do not consider syntax if there is printing mistake, as i am typing code just for showing the concept in my mind 
    public class myclass{ 
    private List<String> mylist=new ArrayList<String>(); 

    public addString(String str){ 
    //code to add string in list 
    } 

    public deleteString(String str){//or passing an index to delete 
    //code to delete string in list 
    } 
} 

ここでは、これら2つの操作を同時に実行したいと考えています。そのために私は2つのスレッドを作成したクラス1つは実行中のaddString()ロジックを実行し、別のtryString()logic.iは各スレッドのコンストラクタにmylistを渡しますが、mylistに追加および削除を実行した後にオブジェクトを返すことができます。

「私がmylistをスレッドのコンストラクタに渡している場合、それはスレッドへのmylistのアドレスを渡し、スレッドはmylistオブジェクトを参照する操作を実行します」と思っていましたが、変更はmylistオブジェクトに反映されません。誰がこれを詳述できますか?

これを達成する最も良い方法は何ですか?

要するに、あるスレッドが最後に要素を挿入している場合、別のスレッドは他のインデックスのある要素を同時に削除する必要があります。

EDIT

私は次のようにそれを行っている:Enno塩路にありがとう

public class myClass { 

    private List<String> mylist = Collections.synchronizedList(new ArrayList<String>()); 
    public myClass(){ 
     mylist.add("abc"); 
     mylist.add("def"); 
     mylist.add("ghi"); 
     mylist.add("jkl"); 
    } 
    public void addString(String str) { 
     mylist.add(str); 
    } 

    public void displayValues() { 
     for (int i = 0; i < mylist.size(); i++) { 
      System.out.println("value is " + mylist.get(i) + "at " + i); 
     } 
    } 

    public void deleteString(int i) { 
     mylist.remove(i); 
    } 
} 

class addThread { 

    public static void main(String a[]) { 
     final myClass mine = new myClass(); 
     Thread t1 = new Thread() { 

      @Override 
      public void run() { 
       mine.displayValues(); 
       mine.addString("aaa"); 
       mine.displayValues(); 
      } 
     }; 
     Thread t2 = new Thread() { 

      public void run() { 
       mine.displayValues(); 
       mine.deleteString(1); 
       mine.displayValues(); 
      } 
     }; 
     t1.start(); 
     t2.start(); 
    } 
} 

はそうする他の方法はありますか?

+0

だろうあなたがスレッドを作っているし、どのように値を挿入、削除しようとしている方法を示しすることはできますか? – gprathour

+1

あなたの質問は非常に混乱しています。あなたは 'myclass'クラスを記述しましたが、あなたの質問でそれを言及してはいけません。 'mylist'は単なる' add'と 'remove'のリストですが、' myclass'には何が必要ですか? 'add'と' delete'を使うスレッドとコードを作るために使うコードを見ることがもっと重要です。 –

+0

@AlexGitelman編集 –

答えて

7

使用同期リスト、それは、スレッドセーフ

使用Collection.synchronizedList(yourPlainList)

+0

あなたは編集を見て、どのように私はこれをCollection.synchronizedList(yourPlainList)を使って実装できますか? –

+0

私は彼がデータの並行操作を要求していたと思いますが、arraylistsでは実行できません。彼はCopyOnWriteArrayListを望んでいます –

+1

共有されているあなたのリストは同期する必要があります –

5

スレッドとオブジェクトインスタンスは異なる概念です。スレッド間でデータを共有する場合は、2つのスレッドから1つのオブジェクトインスタンスにアクセスする必要があります。この場合、このようなことを行う必要があります。

public class MyClass{ 
    private final List<String> mylist = new ArrayList<String>(); 

    public synchronized void addString(String str){ 
     //code to add string in list 
    } 

    public synchronized void deleteString(String str){ 
     //or passing an index to delete 
     //code to delete string in list 
    } 
} 

し、両方のスレッドから同一のオブジェクトインスタンス(mine)を参照する方法を次に

final MyClass mine = new MyClass(); 
Thread t1 = new Thread(){ 
    public void run(){ 
     mine.addString("aaa"); 
    } 
}(); 

Thread t2 = new Thread(){ 
    public void run(){ 
     mine.deleteString("bbb"); 
    } 
}(); 

t1.start(); 
t2.start(); 

注意。 MyClassをスレッドセーフにするために、​​というキーワードを追加しました。これにより、すべての操作が真に「同時に」ではなく順次実行されます。コレクションに対して真の同時操作が必要な場合は、スキップリストのような並行データ構造を使用し、​​というキーワードを取り除く必要があります。

+0

私はプライベートリストを使用しました mylist = Collections.synchronizedList(new ArrayList ());ジガーが指定した通りです。どうもありがとう。 –

関連する問題