【问题标题】:Understanding the Thread Safety of Array list了解数组列表的线程安全
【发布时间】:2016-04-13 14:14:27
【问题描述】:

我试图通过 java 程序了解 ArrayList 如何不是线程安全的。附加的是我的程序。

import java.util.ArrayList;
import java.util.List;
public  class class1 
 {
  static List ar=new ArrayList(1);
  public static void main(String[] args) throws InstantiationException,   
  IllegalAccessException, ClassNotFoundException, InterruptedException 
   {
      Thread t1= new Thread()
      {
          public void run()
          {
              while(true)
              {
                 ar.add(new Object());
              }
          }
      };

      Thread t2=new Thread()
      {
              public void run()
          {
              while(true)
              {
                  ar=new ArrayList(1);
                  ar.add(new Object());
                  ar.add(new Object());
              }
          }
      };

      t1.start();
      Thread.sleep(100);
      t2.start();
      }
    }

我得到的错误是:

  Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 2
  at java.util.ArrayList.add(Unknown Source)
  at class1$1.run(class1.java:22)

我知道异常是由线程引起的。但是,我没有更全面地了解它的实际运作方式。非常感谢任何帮助。

【问题讨论】:

  • 此异常不是由线程引起的,而是由java.lang.ArrayIndexOutOfBoundsException: 2 明确指出的数组超出范围引起的
  • 你是怎么想出这个程序的,你认为它究竟如何证明线程安全与非线程安全?
  • @redFIVE,从技术上讲,Java 中发生的一切都是“由线程引起的”。我认为您的意思是,异常的原因与 ArrayList 由多个线程共享​​>这一事实无关。
  • @jameslarge 当然,这与它有关ArrayList 上使用的唯一函数是 add,在正常情况下(“正常”表示单线程)不应抛出越界。

标签: java multithreading arraylist collections


【解决方案1】:

查看 ArrayList.Add 代码。 数组列表是基于数组的。如果数组已满 - arrayList 将其长度扩展为 2。要扩展数组,必须复制它。当一个线程中调用的“add”扩展了 arrya 并尝试复制数据时,您的代码似乎崩溃了 - 但另一个线程更改了引用。

【讨论】:

  • 关闭,但没有雪茄(虽然没有投票,因为除了猜测和因素之外的一切都是正确的)。交错add 和更改引用不会有任何害处,因为add 将完全在旧对象上完成。这与 2 个 add 方法交错有关。找到他们如何做到这一点实际上并非易事,我鼓励您尝试发现它(提示 - 它在 grow 方法中)。
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 1970-01-01
相关资源
最近更新 更多