2010-09-17 166 views
2

java中的ArrayList是線程安全的,並且它使用數組實現。java數組線程安全

那麼,在java線程中對數組的訪問是否安全?是否需要對數組的訪問進行同步?

回答

7

不,ArrayList不是在Java中是線程安全的。

the docs

注意,此實現不是同步的。如果多個線程同時訪問一個實例,並且至少有一個線程在結構上修改了列表,它必須在外部同步。

你在想Vector,它在內部使用同步嗎? (基本上,每種方法都是同步的。)

+0

它應該與各種讀寫鎖定同步,因爲讀取可以同時進行。如果它使用排他鎖,那麼我不喜歡'Vector' :) – Andrey 2010-09-17 17:51:44

+1

@Andrey:嗯,這正是它所做的。 Vector'完全同步。 (這實際上並沒有使它正確地線程安全......只是每一個單獨的操作。) – 2010-09-17 18:05:23

+0

@ohhh是ArrayList不是線程安全的,但多線程訪問數組的方式是什麼?它在內部是同步的,還是我們必須同步外部訪問? – userv 2010-09-19 08:56:38

1

線程安全的數組會是什麼樣子?您不能添加或移除數組的元素。你所能做的就是給每個成員分配值。

假設你的代碼有

int x = a[2]; 
    a[3] = x; 

那是線程安全的? (提示:可能不是,取決於你想要[2]和[3]的一致性)。

一般來說:從顯着的線程安全開始。把同步放在 - 它並不昂貴。真的想想你的意思。測試它並解決僵局 - 如果你有這樣的問題,你可能沒有想到你正在努力做的事情。只有當你的性能測試真的證明這是你的瓶頸開始變得聰明。

+0

線程安全不能*可能*不可以。它可以是或不是。 – Andrey 2010-09-17 17:52:55

+1

@Andrey - 那麼代碼線程安全嗎?假設數組賦值是原子的,並且忘記了所有的寄存器緩存問題。想象一下圍繞我的兩行代碼進行同步。現在是代碼線程安全嗎?你不知道,你不知道,因爲你需要更多的信息。我的代碼是否打算[2]和[3]始終保持一致?或者我不在乎?如果沒有這些信息,它可能是安全的,但這可能不是。我在說OQ可能會問錯誤的問題。 – djna 2010-09-17 20:02:16

1

Java內存模型將每個數組元素視爲一個單獨的變量。就像任何其他變量一樣,您可能對這樣的變量有線程不安全的操作。

該數組本身是相當線程安全的。

static Object[] a; 

// thread 1 
a = new Object[10]; 

// thread 2 
read a.length // ok 
read a[0]  // ok 
a[0] = something // ok 

有什麼大不了的?如果您使用ArrayList例如,這種行爲是不是安全沒有適當的同步

static ArrayList a; 

// thread 1 
a = new ArrayList(another_collection_with_10_null); 

// thread 2 
a.size(); // unsafe 
a.get(0); // unsafe 
a.set(0, something); // unsafe 

您可能會得到不正確的結果,甚至unsensible結果,或例外。你可能會搞砸列表並使其永久無法使用。