簡體   English   中英

返回Java數組與集合

[英]Returning Java Arrays vs Collections

我正在嘗試在java應用程序中考慮內存分配和多線程的一些設計,這就是我想知道的:

我有一個具有同步集合的類說一個列表,它會在幾秒鍾內更新幾次,但所有更新都發生在類中,而它自己的線程不是來自其他線程。 但是我有許多其他線程調用getCollection()方法並執行foreach以只讀方式迭代其內容。 這是我不知道的:

如果另一個線程正在迭代同步的收集,那么執行更新的單個線程是否必須等到沒有其他線程迭代的時間點?

我的第二個問題是,通過執行.toArray返回集合的數組副本而不是集合本身似乎是有意義的,但是從內存的角度考慮它不會需要分配一個大小的新數組每次收集內容的內容,如果在一個有數千個對象的集合中每秒被調用數百次,那么我不知道是不是有意義。

此外,如果我從不返回集合本身而不是使列表同步不再需要?

將不勝感激任何意見。 謝謝! - 鄧肯

如果另一個線程正在迭代同步的收集,那么執行更新的單個線程是否必須等到沒有其他線程迭代的時間點?

如果你正在討論同步(非並發)集合,那么是。 至於第二個問題,它看起來像是java.util.concurrent.CopyOnWriteArrayList的真實用例。

我建議你使用CopyOnWriteArrayList。 這是線程安全的,可以通過任意數量的線程高效地讀取。 如果您有少量更新,這應該沒問題。

但是,要回答你的問題。 如果在修改時對同步集合進行迭代,則會出現ConcurrentModificationException(COWAL無法獲取此更新)此更新不會被阻止,只有讀者才會遇到問題。

每次調用getCollection時都不會創建副本,而是每次修改集合時創建一個副本(更不常見)這就是COWAL為您所做的事情。

如果按需返回副本,則仍需要同步集合。

處理此問題的最簡單方法可能是保留兩個集合:一個由類本身更新,另一個是在調用getCollection()時返回的volatile字段中的只讀副本。

后者需要通過在適當時更新主集合的過程來重新創建。 這允許您以原子方式更新集合:一次更改多個元素,同時隱藏中間狀態。

如果您的更新不頻繁且每次更新都使集合保持一致狀態,則使用已建議的CopyOnWriteArrayList。

似乎經常更新集合並經常調用#getCollection()。 您可以使用CopyOnWriteArrayList,但每次修改數組時都會創建一個副本。 所以你需要看看它如何影響性能。

另一種選擇是在每次調用#getCollection時對類中的線程進行任務以進行復制。 這將涉及#getCollection等待內部類線程完成。

如果您只是希望#getCollection返回最近的副本而不是最新的副本,那么您可以讓內部線程定期創建在#getCollection中返回的集合的副本。 副本需要是易失性的或者是AtomicReference。

暫無
暫無

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

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