ArrayList.add(int index, E element) 线程不安全吗? [英] Is ArrayList.add(int index, E element) thread unsafe?

查看:30
本文介绍了ArrayList.add(int index, E element) 线程不安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的上一个问题让我想到了这个问题.

My Previous question brought me to this question.

添加函数 ArrayList线程安全?

Is add function of ArrayList thread safe?

我使用以下类制作了一个示例应用程序

I made a sample application with following classes

import java.util.ArrayList;
import java.util.List;


public class ThreadTest
{
    public static List<DummyObject> list = null;
    public static boolean isLoaded = false;
   public static void main(String [] args)
   {
      MyThread t1 = new MyThread(1);
      MyThread t2 = new MyThread(2);

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

   public static void loadObject(){
       if(isLoaded){
           return;
       }
       isLoaded = false;
       try{
       list = new ArrayList<DummyObject>();
       for(int i=0;i<10;i++){
           list.add(i,new DummyObject());
       }}
       catch(Exception e){
           e.printStackTrace();
       }
       isLoaded = true;
   }
}

这些是我的主题

public class MyThread extends Thread
{
   int threadNumber ;
   public MyThread(int threadNumber)
   {
      this.threadNumber = threadNumber;
   }

   @Override
   public void run()
   {
       try {
        sleep(10-threadNumber);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
     System.out.println("Running Thread: " + threadNumber);
     ThreadTest.loadObject();
     if(ThreadTest.isLoaded){
         System.out.println(ThreadTest.list);
         for(int i=0;i<ThreadTest.list.size();i++){
             if(ThreadTest.list.get(i)==null){
                 throw new NullPointerException();
             } 
         }
     }else {
         try {
                sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
         }
   }
}

这是我的虚拟班

public class DummyObject {

}

即使我无法复制我在 上一个问题 ,我有时会收到此错误

Even though I wasn't able to replicate the Null Pointer Exception that I got on my previous question , I sometimes get this error

Exception in thread "Thread-1" java.lang.IndexOutOfBoundsException: Index: 1, Size: 10
    at java.util.ArrayList.add(ArrayList.java:367)
    at ThreadTest.loadObject(ThreadTest.java:25)
    at MyThread.run(MyThread.java:20)

表单 ArrayList 代码这是抛出错误的行:

Form ArrayList Code this is the line thats throwing an error:

if (index > size || index < 0)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);

但是我们可以从异常中看到索引为1,大小为10,所以如果条件满足是不可能的.那么我的假设是正确的,即 arrayList 的 add 函数是线程不安全的还是这里发生了其他事情?

But as we can see from Exception index is 1 and size is 10, so there is no way that if condition is satisfied. So is my assumption correct that add function of arrayList is thread unsafe or is something else going on here?

推荐答案

来自 文档:

(这个类大致相当于 Vector,只是它是不同步的.)

(This class is roughly equivalent to Vector, except that it is unsynchronized.)

您需要自己实现同步,或者更好的是,使用像 矢量.

You need to either implement the synchronization yourself, or better yet, use a synchronized container like Vector.

就您的代码而言,您有 2 个线程运行同一段代码 (loadObject),其中访问/修改了多个静态值.您需要确保每次访问都以同步方式完成.您有 2 个线程,因此您分配了两次 ThreadTest.list 字段,因此其中一个分配是无用的,但更重要的是,该列表中可能会在丢失之前插入一些值,因此这些价值也会丢失.

In the case of your code, you have 2 threads running the same piece of code (loadObject) in which several static values are accessed/modified. You need to make sure that each access is done in a synchronized manner. You have 2 threads, thus you allocate twice the ThreadTest.list field, so one of the allocation is useless, but more importantly, there might be some values inserted in that list before it is lost, so these values become lost as well.

您应该确保在分配列表之前没有分配列表.

You should make sure that the list is not allocated before allocating it.

您的 isLoaded 字段也可能有问题,导致列表中的元素超过 10 个.

You could also have problem with the isLoaded field, leading to more than 10 elements in your list.

这篇关于ArrayList.add(int index, E element) 线程不安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆