简体   繁体   English

为什么我能够同时读取/写入arraylist?

[英]Why i am able to read/write arraylist at same time?

i am using multiple threads here .. one thread is fetching the list and other is adding a name to the list and both these threads are using a shared resource ie ArrayList object it should give concurrentModification something like that which it is not giving or maybe i am not able to use the threads correctly in my code 我在这里使用多个线程..一个线程正在获取列表,另一个正在向列表添加名称,并且这两个线程都使用共享资源,即ArrayList object它应该给concurrentModification一些类似的东西,这不是它给出的,或者我无法在我的代码中正确使用线程

code is as follows : 代码如下:

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"); 
 } 
}

Each of the two threads takes so little time (probably less than 1 microsecond on a modern CPU) that the chance of them actually executing at the same time is extremely low. 两个线程中的每个线程都花费很少的时间(在现代CPU上可能不到1微秒),因此它们实际上同时执行的机会非常低。 You would have to do significant work in both threads to ensure they were active simultaneously. 您必须在两个线程中都进行大量工作,以确保它们同时处于活动状态。

Thread.start() takes some time. Thread.start()需要一些时间。 It's very likely that the first thread has completed before the second begins to use its Iterator -- or vice versa, there's no way to predict which. 第一个线程很可能在第二个线程开始使用其Iterator之前就已经完成-反之亦然,无法预测哪个线程。

One of the problems with concurrency is that we have to use phrases like 'very likely' because we can't predict the order in which things will happen, so the behaviour of some programs becomes inconsistent. 并发性的问题之一是我们必须使用“非常可能”之类的短语,因为我们无法预测事物发生的顺序,因此某些程序的行为变得不一致。

Try putting some Thread.sleep() statements inside the loops, so that you can be more sure that the ArrayList get() s execute while the Iterator is open. 尝试将一些Thread.sleep()语句放入循环内,以便可以更确定在打开Iterator同时执行ArrayList get()

Note that while adding sleeps is a quick and easy way to "fiddle" the timings into long enough periods that you can witness certain conditions occurring, they are almost never the right way to solve thread synchronization issues in real code. 请注意,虽然添加睡眠是一种将时间“弄乱”足够长的时间的简便快捷方法,您可以看到某些情况的发生,但它们几乎永远不是解决实际代码中线程同步问题的正确方法。

As @Slim mentioned its due to the delay in threads while displaying and adding. 正如@Slim提到的,由于显示和添加时线程的延迟。 Modify your code as below by adding Sleep, it would result in concurrentModificationException. 通过添加Sleep如下修改您的代码,这将导致parallelModificationException。

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");
}

Exception: 例外:

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)

ArrayList is not threadsafe. ArrayList不是线程安全的。 You should probably be looking at something like ConcurrentLinkedDeque 您可能应该在看类似ConcurrentLinkedDeque的东西

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能将以下字符串作为输入并将其添加到ArrayList中? - Why am I not able to take the following string as input and add it to an ArrayList? 为什么我无法以文件形式从网站读取HTML内容? - why i am not able to read Html Content from a website in a file? 我无法将所有数据写入文件 - I am not able to write all data to a file 我无法在 Excel 工作表中写入数据 - I am not able to write data in Excel sheet 为什么LinkedList和ArrayList的运行时间不同 - why the running time of the LinkedList and the ArrayList are not the same 将对象的数组列表转换为同一对象的数组时,为什么会出现 ClassCastException? - Why am I getting a ClassCastException when converting an arrayList of objects to an array of the same object? 为什么我在使用 ArrayList 时出现 Time Limit Exceeded (TLE) 错误<string[]>而不是 int[][]?</string[]> - Why am I getting Time Limit Exceeded (TLE) error when using ArrayList<String[]> instead of int[][]? 为什么我可以将 Arrays.asList 方法与为接口 List 声明的对象一起使用,但当它被声明为类 ArrayList 的实例时却不能使用? - Why I am able to use Arrays.asList method with an object declared for interface, List, but not when it is declared as an instance of class ArrayList? 为什么我只能从SI MessageSource中读取/处理一个文件? - Why am I only able to read/processs one file from an SI MessageSource? 为什么我无法使用 Exchange Web 服务 Java API 读取完整的 email 正文? - Why am I not able to read the complete email body using Exchange Web Service Java API?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM