2016-03-21 37 views
0

我在這裏使用多線程..一個線程讀取列表和其他被添加一個名稱列表,這兩個線程使用共享資源,即ArrayList object它應該給concurrentModification類似的東西,它是不給或可能我不能夠在我的代碼正確使用線程爲什麼我能夠同時讀取/寫入數組列表?

代碼如下:

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這給了一個異常? jsut好奇 – Amol

+0

@SarthakMittal檢查併發修改是盡最大努力的基礎上進行的,正如文檔中提到的那樣。即有可能你不會得到例外。 –

回答

3

Thread.start()需要一些時間。很可能第一個線程在第二個線程開始使用它的迭代器之前完成 - 反之亦然,沒有辦法預測哪個線程。

一個併發的問題是,我們必須使用短語,如「非常有可能」,因爲我們無法預知在事情發生的順序,因此一些程序的行爲變得不一致。

嘗試在循環中放入一些Thread.sleep()語句,以便您可以更確定在Iterator打開時執行ArrayList get()

請注意,雖然添加睡眠是一種快速簡便的方法,可將時間「擺到足夠長的時間段內,以便您可以目睹某些情況的發生,但它們幾乎從來都不是以真實代碼解決線程同步問題的正確方法。

+0

我用..它給了相同的結果..ie而取,我得到了增值也..所以這意味着兩個線程simultaeously跑了,並沒有給出任何異常100名的圈 – Amol

+0

我已經處理了相應的評論和投票。 – ChiefTwoPencils

3

每兩個線程需要很短的時間(可能小於1微秒現代CPU上)的他們在同一時間實際執行的機會非常低。你將不得不在兩個線程中進行重要的工作,以確保它們同時處於活動狀態。

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

似乎很奇怪,因爲您已經努力強制執行'ConcurrentModificationException',這與OP想要看到的內容有些相關,但是不能。我認爲這確實爲這篇文章增添了一些價值。從我+1。 –

+0

當然,我投了票。你的開場白是一個錯誤的限定詞。此外,推薦睡眠充其量不是最好的。 – ChiefTwoPencils

相關問題