java批量插入隊列筆記

往數據庫裏插入大量的數據,當然是批量插入最高效,我們設定一個題目,每次把數據放入隊列,當數據大於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);
		}
	}

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章