2016-03-21 4 views
0

ここでは複数のスレッドを使用しています.1つのスレッドがリストをフェッチしていて、他のスレッドがリストに名前を追加していて、両方のスレッドが共有リソースを使用しています。ArrayList objectconcurrentModificationは、私は私のコードで正しくスレッドを使用することはできませんよなぜ私は同時にarraylistを読み書きできますか?

コードは次のとおりです。

import java.util.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class threadprac 
{ 
    public static void main(String args[]){ 

     ArrayList<String> shared; 
     shared = new ArrayList<>(); 
     String[] arr=new String[]{"amol","robin","shanu","saaru","mohit"}; 
     for(String n:arr) 
      shared.add(n); 
     Thread tf = new Thread(new fetch(shared)); 
     Thread tm = new Thread(new manipulate(shared)); 
     tm.setName("thread-M"); tf.setName("thread-F"); 
     tf.start(); 
     tm.start(); 
     try { 
     Thread.currentThread().sleep(2000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(threadprac.class.getName()).log(Level.SEVERE, null, ex); 
    } 
     for(String n:shared) 
      System.out.print(n+" "); 

}  
} 

class fetch implements Runnable 
{ 
ArrayList<String> f; 
fetch(ArrayList shared){ 
    this.f=shared; 
    } 
@Override 
public void run(){ 
    displayList(); 
    } 
void displayList(){ 
    Iterator<String> itr=f.iterator(); 
    while(itr.hasNext()){ 
     String name = itr.next(); 
     System.out.print(name+" "); 
    } 
    System.out.println(); 
    } 
} 

class manipulate implements Runnable 
{ 
ArrayList<String> m; 
manipulate(ArrayList shared){ 
    this.m=shared; 
} 
@Override 
public void run(){ 
    addName(); 
} 
void addName(){ 
    m.add("rohit"); 
} 
} 
+2

、それはそれを行うには、単に安全ではないですし、あいまいな結果 –

+0

@SarthakMittalを生成することができます..私は、フェイルファストを使用していますイテレータと私はイテレータを宣言した後にリストを変更しています... shuldn​​tこれは例外を与えますか?好奇心が強い。 – Amol

+0

@SarthakMittalの同時修正のチェックは、ドキュメントで述べられているように、ベストエフォート方式で行われます。 e。あなたが例外を取得しないチャンスがあります。 –

答えて

3

Thread.start()はしばらく時間がかかります。 2番目のスレッドがIteratorを使用する前に最初のスレッドが完了している可能性が高く、その逆の場合もあります。

並行性の問題の1つは、「非常に可能性が高い」というようなフレーズを使用する必要があるということです。なぜなら、起こる順序を予測することができないため、一部のプログラムの動作が矛盾するからです。

Thread.sleep()ステートメントをループ内に配置すると、Iteratorが開いている間にArrayList get()が実行されることをより確実に確認できます。

スリープを追加すると、特定の条件が発生するのを十分に確認できるように、タイミングを「フィドル」することが簡単で簡単な方法です。実際のコードでスレッド同期の問題を解決する方法としては決して適切ではありません。

+0

に対処していません。100個の名前のループを使用しました。同じ結果を返しました。フェッチ中に追加値も得られました。つまり、両方のスレッドがsimultaeously実行され、 – Amol

+0

私はそれに応じてコメントと投票を処理しました。 – ChiefTwoPencils

3

二つのスレッドのそれぞれが、そのので、少し時間(最近のCPU上で、おそらく1マイクロ秒未満)を取り彼らが実際に同時に実行する可能性は極めて低いです。同時にアクティブになっていることを確認するには、両方のスレッドで重要な作業を行う必要があります。

0

ArrayListはスレッドセーフではありません。あなたはおそらく何かを見ているべきですConcurrentLinkedDeque

+0

この回答は実際に質問 –

2

@Slimは、表示および追加中のスレッドの遅延のために説明しました。 Sleepを追加してコードを変更すると、concurrentModificationExceptionが発生します。

void displayList() throws InterruptedException { 
     Iterator<String> itr = f.iterator(); 
     while (itr.hasNext()) { 
      String name = itr.next(); 
      Thread.sleep(100); 
      System.out.print(name + " "); 
     } 
     System.out.println(); 
    } 

... 

    void addName() throws InterruptedException { 
    Thread.sleep(100); 
    m.add("rohit"); 
} 

例外:私たちは、あなたがやっていることを行うことができないと言ったことがないです

amol Exception in thread "thread-F" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 
    at java.util.ArrayList$Itr.next(ArrayList.java:851) 
    at fetch.displayList(TestClass.java:43) 
    at fetch.run(TestClass.java:33) 
    at java.lang.Thread.run(Thread.java:745) 
+0

なぜdownvote?私はこれをテストして、concurrentModifcationExceptionを取得しました。コードもうまく見えます。 –

+0

OPが見たいと思っていたものに幾分関係していますが、できなかった「ConcurrentModificationException」を強制するように努力しているので、奇妙です。私はこれがポストにいくつかの価値を追加したと思った。私の+1。 –

+0

確かに、私はそれを落札しました。あなたの開始文は偽の修飾子です。さらに、睡眠を推薦することは、せいぜい最高ではない。 – ChiefTwoPencils

関連する問題