2016-03-21 38 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

相关问题