Java雙緩衝佇列實現

2021-07-30 17:21:42 字數 1962 閱讀 4806

在某一模組中,需要將網路接收到的資料存入oracle中。這是乙個典型的生產者消費者場景,可以使用訊息佇列隔離生產者和消費者。由於接收的資料頻度很高,而oracle的插入速度較慢,為不影響接收端吞吐量,選擇了雙緩衝佇列作為訊息佇列。雙緩衝佇列的原理是一般情況下生產者使用寫佇列,消費者使用讀佇列,兩個執行緒不需要做同步保護。當讀佇列消費完的時候,將讀寫佇列交換,生成者使用空的讀佇列,消費者使用寫佇列。雙緩衝佇列只需在這時對讀寫佇列進行同步保護即可,可大幅提高效能。

**主要由乙個雙緩衝佇列類、乙個生產者類和乙個消費者類組成。需要說明的是,在我的這種實現裡,只對寫佇列做了同步保護,這是因為在我的應用裡讀寫佇列交換由消費者控制,這樣一來,讀佇列的使用以及交換全在消費者執行緒,讀佇列也就沒必要同步了。如果改為定時交換的話,就必須對讀佇列也加保護了。

該類以單例模式實現,queue為單例物件。其中,emp是我們在佇列中要快取的物件類,如果型別多的話可以將雙緩衝佇列類改造為模板類。成員變數包含兩個列表,乙個用來讀,乙個用來寫。幾個介面,push用來新增新訊息,getwritelistsize獲取寫佇列當前大小,getreadlist獲取讀列表,swap用來交換讀寫列表。

public class doublebufferqueue 

public static doublebufferqueue getinst()

public void push(emp value) }

public int getwritelistsize() }

public listgetreadlist()

public void swap()

}}

寫入控制:比如當寫佇列已經快取了一萬個例項時,暫停寫入,直到消費者執行緒用完讀佇列並交換讀寫佇列。這種方式可能會導致網路吞吐量的降低,但如果能提高消費者效率就可以減少這種降低,比如採用批處理提高oracle的插入速度。

public class writer implements runnable 

public boolean connect(string server, int port)

return true; }

public void run() catch (interruptedexception e)

}queue.push(emp);

} catch (netioexception e)

} }}

消費者類是乙個讀執行緒,負責將讀佇列的元素寫入資料庫(**做了改動,寫入資料庫改為寫入檔案)。讀執行緒不斷檢測讀佇列,當讀佇列有資料時,遍歷讀佇列讀取元素寫入資料庫。這裡需要注意的是,在讀執行緒裡做了交換讀寫佇列的控制,只有當讀隊列為空且寫佇列大小超過1000時才進行交換。這樣做的好處一是可以避免交換頻率過高,二是保證一次獲取一定量的例項,可以使用資料庫的批處理來提高寫入效率。另外,在讀佇列使用完後,記得要清空讀佇列。

public class reader implements runnable  else 

} catch (interruptedexception e)

}int counter = 0;

filewriter fw = new filewriter("result.txt", true);

for (emp value : readlist)

fw.close();

system.out.println("read: " + counter);

readlist.clear();

} } catch (ioexception e)

}}

應用部分較為簡單,建立兩個執行緒,開啟執行即可。讀寫執行緒中的讀寫控制考慮的比較簡單,有好想法的朋友歡迎交流,謝謝!

public static void rwtest()

雙緩衝佇列

前段時間,做了個 雙緩衝佇列 可是測試的效果就是不怎麼明顯,理論完全都在這裡,可是就是看不到效果。昨天在胡總的提示下,終於意識到不該用阻塞佇列,換成普通的list物件,這樣效果就明顯多啦 又重新寫了一篇文件,如下 好,31毫秒。這是我們的第一種解決方法,下面再來看第二種解決方法 其實我們在facto...

雙緩衝佇列

例一 首先,使用arrayblockingqueue類建立乙個大小為10的雙緩衝佇列queue 然後,迴圈20次向佇列queue中新增元素,如果5秒內元素仍沒有入隊到佇列中,則返回false 如下 public class demo03 catch interruptedexception e 測試...

實現乙個雙緩衝佇列

在生產者 消費者模式中,我們常常會使用到佇列,這個佇列在多個執行緒共享訪問時存在互斥和競爭操作,意味著每次訪問都要加鎖。如何更好的如何減少鎖競爭次數呢 今天要介紹的雙緩衝佇列就是個不錯的選擇。雙緩衝佇列就是衝著同步 互斥的開銷來的。我們知道,在多個執行緒併發訪問同乙個資源的時候,需要特別注意執行緒的...