2012-06-22 53 views
3

我有兩個線程,一個閱讀流和從他們的內容中產生數據對象。將一組對象從一個線程傳遞到另一個線程的最快數據存儲是什麼?

然後我必須將它們傳遞給第二個線程,將它們寫入數據庫。

我想分開兩個任務(這就是爲什麼我帶兩個線程),因爲流和數據庫上的I/O性能不同。在某些情況下,數據流速度很快,有時數據庫會有一些滯後。

所以我想在它們之間放一些(非常簡單的!)數據存儲。

我的第一個想法是一個FILO解決方案,必須是線程安全的,應該是快速的(沒有花哨的東西,只是放和拉)。訂單無關緊要。在某些時候,存儲中可能會有大約100,000個條目(在使用db進行一秒鐘ping後,情況就會如此)。

每個物體的佔地面積很小,< 1kb。

你會推薦給我什麼?

回答

6

這正是生產者 - 消費者模式。看看BlockingQueue及其實現。

這裏是我的blog示例代碼:

public class Producer implements Runnable { 
    private BlockingQueue queue; 

    public Producer(BlockingQueue queue) { 
     this.queue = queue; 
    } 

    @Override 
    public void run() { 
     //Produce 1000 products 
     for (int i = 0; i < 1000; i++) { 
      queue.put(new Product()); 
      System.out.println("PRODUCED PRODUCT"); 
     } 
    } 
} 
public class Consumer implements Runnable { 
    private BlockingQueue queue; 

    public Consumer(BlockingQueue queue) { 
     this.queue = queue; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      Product product = queue.take(); 
      System.out.println("CONSUMED PRODUCT"); 
     } 
    } 
} 

And here is the calling code: 
BlockingQueue queue = new ArrayBlockingQueue(50); 

Producer producer = new Producer(queue); 
new Thread(producer).start(); 

Consumer consumer = new Consumer(queue); 
new Thread(consumer).start(); 
1

不要線程之間複製你的對象。將指針指向線程之間的對象。並嘗試在內存中保持對象順序。這樣當你在線程之間傳遞一批對象時,CPU只需要在CPU之間重新映射幾個內存頁。

在大於OS內存頁大小的批處理線程之間傳遞對象。

因此,爲了獲得理想的性能,您希望生產者使用一組內存頁面,並使用另一組頁面。 CPU將確保一個內核使用的頁面映射到該內核上的本地存儲以及另一個內核上的其他頁面。

如果你不這樣做,那麼內存頁在內核之間來回切換。

如果複製,那麼它是相同的。當寫入器線程寫入一個頁面,並且讀取器線程在同一頁面上讀取時,CPU花費時間確保兩個內核看到相同的數據。

所以,我會讓讀者讀一堆對象說16k的價值,而不是使它們可用於消費者線程。一旦你填充了這些頁面,將它們釋放到處理器線程中,並分配另一個16k數據塊來開始填充更多的對象。

相關問題