簡體   English   中英

Java並發 - 寫入同一個數組的不同索引

[英]Java concurrency - writing to different indexes of the same array

假設我有一個數據數組,2個線程可以安全地同時寫入同一個數組的不同索引嗎? 我關心寫入速度,我想同步'get index to write at'位與實際寫入。

我正在編寫代碼,讓我假設2個線程不會獲得相同的索引。

對於數組中的兩個不同索引,相同的規則適用於兩個單獨的變量。

Java語言規范中的“線程和鎖定”一章首先說明:

17.4.1共享變量

[...]

所有實例字段,靜態字段和數組元素都存儲在堆內存中。 在本章中,我們使用術語變量來指代字段和數組元素

這意味着您可以安全地同時寫入兩個不同的索引。 但是 ,如果要確保使用者線程看到生產者線程寫入的最后一個值,則需要將寫入/讀取同步到同一索引。

在兩個不同的線程中修改兩個不同的變量是安全的。 可以將修改陣列中的兩個不同元素與在不同存儲器地址下修改兩個不同變量進行比較,至少就OS而言。 所以是的 ,它是安全的。

嗯,是的,這在技術上是正確的,但是這個答案有很多警告,讓我感到非常擔心,告訴你是的。 因為雖然您可以寫入數組中的兩個不同位置,但如果不遇到並發問題,則無法執行其他操作。 真正的問題在於,如果你能做到這一點,接下來要做什么?

如果您有計數器變量隨陣列寫入不同位置而移動,則可能會遇到並發問題。 當你的數組填滿時,你可能有兩個線程嘗試寫入同一個位置。 如果你可能有一個數組的讀者可以讀取正在寫入的相同位置,那么你將遇到並發問題。 因此,如果您從未計划閱讀它,那么寫不會做任何事情,我認為當你去添加閱讀器時(你將不得不鎖定你的作家)你會遇到並發問題。 那么問題是你是否沒有移動線程所寫的內容以阻止它寫入數據? 如果你沒有移動線程寫入的頭部為什么使用數組? 只是給他們各自的Latches或他們自己的變量寫入,並真正保持它們分開。

如果沒有全面了解你的意圖,說“是”可能會讓你陷入危險而不考慮你為什么要做你正在做的事情。

看看CopyOnWriteArrayList ,只要你對arrayList沒問題。 從其文件,

ArrayList的線程安全變體,其中通過創建底層數組的新副本來實現所有可變操作(添加,設置等)。

這通常成本太高,但是當遍歷操作大大超過突變時,它可能比替代方法更有效,並且在您不能或不想同步遍歷但需要排除並發線程之間的干擾時非常有用。

CopyOnWriteArrayList的實例表現為List實現,允許多個並發讀取,並且讀取與寫入同時發生。 它的方式是每次更改列表時制作一個全新的列表副本。

讀取不會阻塞,並且只能有效地支付易失性讀取的成本; 寫入不會阻止讀取(反之亦然),但一次只能進行一次寫入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM