【问题标题】:exception in accessing vector while accessing elements [closed]访问元素时访问向量的异常[关闭]
【发布时间】:2013-05-29 18:10:02
【问题描述】:

我正在尝试调整我对核心 Java 和多线程的概念。在阅读我发现的一些书时 如果向量被另一个线程以某种方式访问​​,下面的代码可能会抛出ArrayIndexOutOfBoundsException

for (int i = 0; i < vector.size(); i++){
   doSomething(vector.get(i));
}

我确实尝试了很多但无法弄清楚如何? 谁能帮我解决这个问题。

【问题讨论】:

  • 仅从这段代码,是不可能说的。 doSomething 是做什么的?是否有任何其他线程可能并行访问vector
  • 如果另一个线程在你处理它时删除了向量的一个元素,你可能会得到那个异常
  • vector.get(i) 如果i 大于向量的当前元素计数,将抛出异常。
  • 一个线程正在运行该代码。它检查i 是否小于向量的大小。在它执行vector.get() 之前,其他一些线程可以删除向量中的一个元素。当第一个线程到达get() 时,它将失败,因为向量中不再有那么多元素。
  • @OliCharlesworth 这个例子只有这个片段,我现在明白了。最初我认为仅此代码就可以抛出此异常。现在我意识到

标签: java multithreading exception vector


【解决方案1】:

Vector 已同步所有字段。在这种情况下,我们执行诸如获取vertor的大小之类的操作,然后我们尝试稍后访问i元素。它们都是同步的,但它们是及时分布的,我们得到vertor.size()vector.get(i)之间没有同步,所以我们当前的线程可以暂停,向量可以被另一个线程修改,所以向量的大小可能将被改变。例如:

public class TestClass {
    private static final Vector vector = new Vector();

    public static void iterate() {
        for (int i = 0; i < vector.size(); i++) {
            doSomething(vector.get(i));
        }
    }

    public static void main (String... args) {
            //initialize vector and fill it
        new Thread( new Runnable() {
            @Override
            public void run() {
                iterate();
            }
        }, "A").start();

        new Thread( new Runnable() {
            @Override
            public void run() {
                vector.clear();
            }
        }, "B").start();
    }

    private static void doSomething(Object object) {
        //DO SMTHNG.
    }
}

在这种情况下,虽然线程 A 将遍历向量,但线程 B 可以清除它,因此 i 可以大于新向量的大小(在本例中为 0)。解决此问题的最简单方法是使用 synchronized (vector) {...} 块覆盖 iterate() 方法体或使用更复杂的方法。

【讨论】:

  • 非常感谢。我明白了原因。正如我在问题评论中提到的那样,我认为单独的代码可能会导致异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 2018-12-16
相关资源
最近更新 更多