我正在嘗試調用我關於核心Java和多線程的概念。當讀一些書時,我發現 下面的代碼可能會拋出ArrayIndexOutOfBoundsException
如果矢量以某種方式被另一個線程訪問。在訪問元素時訪問向量中的異常
for (int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
我真的嘗試了很多,但無法弄清楚如何? 任何人都可以幫助我。
我正在嘗試調用我關於核心Java和多線程的概念。當讀一些書時,我發現 下面的代碼可能會拋出ArrayIndexOutOfBoundsException
如果矢量以某種方式被另一個線程訪問。在訪問元素時訪問向量中的異常
for (int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
我真的嘗試了很多,但無法弄清楚如何? 任何人都可以幫助我。
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()
方法體或使用更復雜的方法。
非常感謝。 我明白了。正如我在問題評論中提到的那樣,我一直認爲代碼本身可能導致異常。 – daksh
僅憑這個代碼,就不可能說。 「doSomething」做什麼?有沒有其他線程可以並行訪問'vector'? –
如果另一個線程在處理它時刪除了該矢量的元素,則可能會得到該異常 – cmbaxter
如果'i'大於矢量的當前元素數,'vector.get(i)'將拋出異常。 – NINCOMPOOP