往數據庫裏插入大量的數據,當然是批量插入最高效,我們設定一個題目,每次把數據放入隊列,當數據大於1000條或者時間大於5分鐘後把數據批量入庫
隊列處理代碼:
package bathQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
/**
* <p>Title: BatchQueue.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2014</p>
* @author 雪含心
* @date 2014年3月1日
*/
public class BatchQueue<T> {
// 默認間隔處理隊列時間
private static int DEFAULT_TIME = 5000;
// 默認隊列處理長度
private static int DEFAULT_COUNT = 2000;
// 設置隊列處理時間
private long handleTime;
// 設置隊列處理長度
private int handleLength;
// 阻塞隊列
ArrayBlockingQueue<T> queue = new ArrayBlockingQueue<T>(20000);
// 回調接口
private QueueProcess<T> process;
// 用來存放從隊列拿出的數據
private List<T> dataList;
// 往隊列添加數據
public void add(T t){
queue.add(t);
}
// 清理生成的list
public void clearList(){
dataList = null;
dataList = new ArrayList<T>();
}
/**
* 最原始的構造方法,使用這個構造方法設置默認的隊列處理時間和數量
* @param process
*/
public BatchQueue(QueueProcess<T> process){
this(DEFAULT_TIME, DEFAULT_COUNT, process);
}
/**
* 可以設置隊列的處理時間和處理長度
* @param handleTime
* @param handleQueueLength
* @param process
*/
public BatchQueue(int handleTime, int handleQueueLength, QueueProcess<T> process){
this.process = process;
this.handleTime = handleTime;
this.handleLength = handleQueueLength;
start();
}
private void start(){
dataList = new ArrayList<T>(handleLength);
DataListener listener = new DataListener();
new Thread(listener).start();
}
// 隊列監聽,當隊列達到一定數量和時間後處理隊列
class DataListener implements Runnable{
@Override
public void run() {
long startTime = System.currentTimeMillis();
T t = null;
while(true){
try {
// 從隊列拿出隊列頭部的元素,如果沒有就阻塞
t = queue.take();
if(null != t){
dataList.add(t);
}
if(dataList.size() >= DEFAULT_COUNT){
startTime = callBack(dataList);
continue;
}
long currentTime = System.currentTimeMillis();
System.out.println("currentTime - startTime" + (currentTime - startTime) + "handleTime==>" + handleTime);
if(currentTime - startTime > handleTime){
startTime = callBack(dataList);
continue;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private long callBack(List<T> dataList) {
// 處理隊列
try{
System.out.println(dataList);
process.processData(dataList);
}catch(Exception e){
e.printStackTrace();
}finally{
// 清理掉dataList中的元素
clearList();
}
return System.currentTimeMillis();
}
}
}
/**
* add 增加一個元索 如果隊列已滿,則拋出一個IIIegaISlabEepeplian異常
remove 移除並返回隊列頭部的元素 如果隊列爲空,則拋出一個NoSuchElementException異常
element 返回隊列頭部的元素 如果隊列爲空,則拋出一個NoSuchElementException異常
offer 添加一個元素並返回true 如果隊列已滿,則返回false
poll 移除並返問隊列頭部的元素 如果隊列爲空,則返回null
peek 返回隊列頭部的元素 如果隊列爲空,則返回null
put 添加一個元素 如果隊列滿,則阻塞
take 移除並返回隊列頭部的元素 如果隊列爲空,則阻塞
*/
數據處理抽象類
package com.zh.utils;
import java.util.List;
/**
* 批量數據回調接口
* @author zhanghua
*
* @param <T>
*/
public interface BatchQueueCallback<T> {
/**
* 用於接收批量數據
* @param list 批量數據
*/
public abstract void batch(List<T> list);
}
數據庫處理示例
package bathQueue;
import java.util.List;
/**
* <p>Title: DataInsert.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2014</p>
* @author 雪含心
* @param <T>
* @date 2014年3月1日
*/
public class DataInsert<T> extends QueueProcess<T> {
@Override
public void processData(List<T> list) {
}
public static void main(String[] args) throws Exception{
DataInsert back = new DataInsert<>();
BatchQueue<String> queue = new BatchQueue<String>(back);
for(int i = 0; i < 20000; i ++){
queue.add("a" +i);
Thread.sleep(2000);
}
}
}