簡體   English   中英

Java-最有效的隨機訪問多線程列表

[英]Java - Most efficient random-access multi-threaded list

選擇的列表結構:

同步的LinkedList。

場景:

我的程序需要在網格中渲染一些(而不是計算)生成的圖像。 每當某些數據值更改(在另一個線程上)時,這些圖像都必須更新,因此,我有一個渲染隊列來管理此圖像。

渲染隊列是一個同步的LinkedList,在低優先級線程上,它會不斷進行迭代以檢查是否需要執行某些渲染工作。 由於圖像基於各種數據,每個數據都可以獨立更改,因此我需要某種形式的隊列來組合更改。

數據往往會成塊地變化,因此當一大批數據通過時,我會看到一條虛構的線沿着該區域重新渲染圖塊。 為了更好地說明這一點,我決定而不是按照標准順序進行渲染,而是以隨機順序進行渲染(以提供“溶解進/出”效果)。

它看起來很可愛,但是唯一的問題是,完成此效果運行所需的時間有明顯不同。

問題:

我已經提出了一些原因,原因是隨機訪問此列表而不是迭代訪問此列表會導致如此顯着的延遲。 首先,隨機數生成器的nextInt方法可能占用大量時間。 其次,由於它是一個LinkedList,所以當列表的大小在4000s范圍內時,獲取第n個條目也可能很重要。

還有其他可能導致我忽略的延遲原因嗎? 與其使用隨機數生成器,甚至不使用鏈表,我還應該如何有效地實現隨機訪問並從列表中刪除? 如果您已經閱讀了該方案,也許您可​​以想到另一種我可以完全解決的方案?

要求:

  • 多線程添加和修改列表。
  • 隨機訪問和從列表中刪除項目。
  • 高效的操作,具有大數據集和運行次數

您可以使用ArrayList以及幾個簡單的操作來非常有效地實現此目的。

  • 要進行插入,請始終將新作品插入列表的末尾(攤銷的固定時間操作)。
  • 要提取隨機的作品,請選擇一個隨機數i ,將i的元素與列表末尾的元素交換,然后提取並返回該新的最后一個元素。

這是代碼(未經測試,未經編譯):

class RandomizedQueue<T> { 
  private final List<T> workItems = new ArrayList<>();
  private final Random random;

  RandomizedQueue(Random random) {
    this.random = random;
  }

  public synchronized void insert(T item) {
    workItems.add(item);
  }

  public synchronized T extract() {
    if (workItems.isEmpty()) {
      return null;  // or throw an exception
    }

    int pos = random.nextInt(workItems.size());
    int lastPos = workItems.size() - 1;
    T item = workItems.get(pos);
    workItems.set(pos, workItems.get(lastPos));
    return workItems.remove(lastPos);
  }
}

您也許可以使用PriorityQueue,並在將內容添加到此隊列時為每個項目分配一個隨機優先級。 由於渲染已被隨機化,因此它始終可以始終位於隊列的頂部。 插入PriorityQueue中的“隨機”位置(或更好的放置,具有隨機優先級)確實非常快。

暫無
暫無

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

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