首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

高頻數據採集緩衝區設計:環形缓冲區與生產者消費者模式實現無鎖讀寫

     編輯:程式設計疑難解答

場景

每秒 200 條波形數據點,需實時繪製,要求零丟包、低延遲、UI 線程不阻塞。

環形緩衝區

class RingBuffer<T> {
    private final T[] buffer;
    private int writeIdx = 0, readIdx = 0;
    private final AtomicInteger count = new AtomicInteger(0);
    
    @SuppressWarnings("unchecked")
    public RingBuffer(int capacity) { buffer = (T[]) new Object[capacity]; }
    
    public boolean offer(T item) {
        int c = count.get();
        if (c == buffer.length) return false; // 滿,丟包或阻塞
        buffer[writeIdx] = item;
        writeIdx = (writeIdx + 1) % buffer.length;
        count.incrementAndGet();
        return true;
    }
    
    public T poll() {
        if (count.get() == 0) return null;
        T item = buffer[readIdx];
        buffer[readIdx] = null; // GC 友好
        readIdx = (readIdx + 1) % buffer.length;
        count.decrementAndGet();
        return item;
    }
}

生產者-消費者線程

  • 生產者 (采集線程):循環 buffer.offer(data),滿時可選擇覆蓋最舊或阻塞。
  • 消費者 (UI 線程/繪圖線程):定時器/Handler 每 16ms 批量 poll() 取出數據點,調用 invalidate() 重繪。

進階:雙緩衝區

兩個 RingBuffer 交換引用,消費者鎖定一個讀取,生產者寫入另一個,完全無鎖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved