62,621
社区成员
发帖
与我相关
我的任务
分享package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* 这个代码应该是楼主说的那个,当满200条记录时,产生一个事件。<br/>
* 然后,将事件(本例通过eventPipe)传递给处理线程,进行处理。
* <p>
* 创建时间:2009-11-9 下午09:07:07
* @author 侯磊
* @since 1.0
*/
public class EventModelAction extends AbstractDBAction implements CollectAction {
private static final int MaxSize = 200;
private List<POJO> cache = new ArrayList<POJO>(MaxSize);
private Queue<Event> eventPipe = new ArrayBlockingQueue<Event>(1);
private EventProcessor thread = new EventProcessor();
public EventModelAction(){
if(thread.running==false){
thread.running=true;thread.start();
}
}
/**
* 事件类。在本程序中,这个类纯属鸡肋。<br/>
* 旨在说明程序的框架内容。
* <p>
* 创建时间:2009-11-9 下午09:11:37
* @author 侯磊
* @since 1.0
*/
static class Event{
Collection<POJO> beans;
}
/** 将缓冲区的数据持久化。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#flush()
*/
public void flush() throws SQLException {
if(cache.size()>0){
Event e = new Event();
e.beans = cache;
eventPipe.add(e);
cache = new ArrayList<POJO>(MaxSize);
}
}
/** 持续放入待持久化的对象。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#put(houlei.csdn.mutiThread.batch2DB.POJO)
*/
public void put(POJO bean) throws SQLException {
cache.add(bean);
if(cache.size()>=MaxSize){
Event e = new Event();
e.beans = cache;
eventPipe.add(e);
cache = new ArrayList<POJO>(MaxSize);
}
}
class EventProcessor extends Thread{
private volatile boolean running = false;
public void run(){
while(running){
Event e = eventPipe.poll();
try {
fetch(e.beans);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}
/**
* 示例代码
*/
public static void main(String[] args) throws SQLException {
boolean hasMorePOJOs = true;
CollectAction act = new EventModelAction();
while(hasMorePOJOs){
POJO bean = new POJO(){};
act.put(bean);
}
act.flush();
}
}
package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 如果是我,我会按照下面的思路进行处理。<br/>
* 就是使用线程池来批量更新。<p/>
* 如果就一个线程进行数据的收集,可以将synchronized去掉。
* <p>
* 创建时间:2009-11-9 下午09:23:49
* @author 侯磊
* @since 1.0
*/
public class MySimpleAction extends AbstractDBAction implements CollectAction {
private static final int MaxSize = 200;
private List<POJO> cache = new ArrayList<POJO>(MaxSize);
private static ExecutorService pool = Executors.newCachedThreadPool();
/** 将缓冲区的数据持久化。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#flush()
*/
public synchronized void flush() throws SQLException {
if(cache.size()>0){
pool.execute(new Processor(cache));
cache = new ArrayList<POJO>(MaxSize);
}
}
/** 持续放入待持久化的对象。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#put(houlei.csdn.mutiThread.batch2DB.POJO)
*/
public synchronized void put(POJO bean) throws SQLException {
cache.add(bean);
if(cache.size()>=MaxSize){
pool.execute(new Processor(cache));
cache = new ArrayList<POJO>(MaxSize);
}
}
class Processor implements Runnable{
private Collection<POJO> beans;
public Processor(Collection<POJO> beans){
this.beans=beans;
}
public void run(){
try {
fetch(beans);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 示例代码
*/
public static void main(String[] args) throws SQLException {
boolean hasMorePOJOs = true;
CollectAction act = new MySimpleAction();
while(hasMorePOJOs){
POJO bean = new POJO(){};
act.put(bean);
}
act.flush();
}
}
package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
/**
* 对插入数据库操作的抽象。不同的实现类,采用不同的实现方式。
* <p>
* 创建时间:2009-11-9 下午08:02:16
* @author 侯磊
* @since 1.0
*/
public interface CollectAction {
/**
* 你可以把这个方法看成是向队列里插入数据对象。
*/
public abstract void put(POJO bean)throws SQLException;
/**
* 你可以理解成,如果队列里有剩余数据,通过该方法把剩余数据更新至数据库。
*/
public abstract void flush()throws SQLException;
}
package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
import java.util.Collection;
/**
* 这个抽象类,其实,是要放置数据库相关的资源。
* 用于持久化操作的。
* <p>
* 创建时间:2009-11-9 下午08:15:42
* @author 侯磊
* @since 1.0
*/
public abstract class AbstractDBAction {
//这里可以放置一些数据库资源。比如:java.sql.Collection之类的东西。
/**
* 将参数集合中的所有数据,进行批量更新。
*/
public void fetch(Collection<POJO> beans)throws SQLException{
//实现数据库数据的批量更新。(楼主要求的应该是200条记录更新一次.)
}
}
package houlei.csdn.mutiThread.batch2DB;
/**
* 要存入数据库映射对象的抽象。用于举例说明。并无他用。
* <p>
* 创建时间:2009-11-9 下午08:04:04
* @author 侯磊
* @since 1.0
*/
public interface POJO {
}
package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 使用单一线程来完成,数据库的批量更新。<br/>
* 数据的接收、持久化都由同一线程来执行。
* 理论上不存在线程同步问题。
* <p>
* 创建时间:2009-11-9 下午08:07:40
* @author 侯磊
* @since 1.0
*/
public class SingleThreadAction extends AbstractDBAction implements CollectAction {
private static final int MaxSize = 200;
private List<POJO> cache = new ArrayList<POJO>(MaxSize);
/** 每放入MaxSize个数据对象,批量更新一次数据库。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#put(houlei.csdn.mutiThread.batch2DB.POJO)
*/
public void put(POJO bean) throws SQLException {
cache.add(bean);
if(cache.size()>=MaxSize){
fetch(cache);
cache.clear();
}
}
/** 将缓冲区的数据持久化。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#flush()
*/
public void flush() throws SQLException {
if(cache.size()>0){
fetch(cache);
cache.clear();
}
}
/**
* 示例代码
*/
public static void main(String[] args) throws SQLException {
boolean hasMorePOJOs = true;
CollectAction act = new SingleThreadAction();
while(hasMorePOJOs){
POJO bean = new POJO(){};
act.put(bean);
}
act.flush();
}
}
package houlei.csdn.mutiThread.batch2DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* 楼主说的轮询线程执行批量更新。
* <p>
* 创建时间:2009-11-9 下午08:35:40
* @author 侯磊
* @since 1.0
*/
public class PollThreadAction extends AbstractDBAction implements CollectAction {
private static final int MaxSize = 200;
private PollThread thread = new PollThread();
private Queue<POJO> cache = new ArrayBlockingQueue<POJO>(MaxSize+MaxSize/2);
public PollThreadAction(){
if(thread.running==false){
thread.running=true;thread.start();
}
}
/** 将缓冲区的数据持久化。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#flush()
*/
public synchronized void flush() throws SQLException {
ArrayList<POJO> list = new ArrayList<POJO>(MaxSize);
POJO bean = null;
while((bean = cache.poll())!=null){
list.add(bean);
}
fetch(list);
}
/** 持续放入待持久化的对象。
* @see houlei.csdn.mutiThread.batch2DB.CollectAction#put(houlei.csdn.mutiThread.batch2DB.POJO)
*/
public void put(POJO bean) throws SQLException {
cache.add(bean);
}
/**
* 轮询线程。每隔一个周期轮询缓冲区的大小,并批量更新。
* <p>
* 创建时间:2009-11-9 下午09:03:18
* @author 侯磊
* @since 1.0
*/
class PollThread extends Thread{
private volatile boolean running = false;
private static final long Cycle = 500;
public void run(){
while(running){
if(cache.size()>=MaxSize){
try {
ArrayList<POJO> list = new ArrayList<POJO>(MaxSize);
for(int i=0;i<MaxSize;i++){
list.add(cache.poll());
}
fetch(list);
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(Cycle);
} catch (InterruptedException e) {
}
}
}
}
/**
* 示例代码
*/
public static void main(String[] args) throws SQLException {
boolean hasMorePOJOs = true;
CollectAction act = new PollThreadAction();
while(hasMorePOJOs){
POJO bean = new POJO(){};
act.put(bean);
}
act.flush();
}
}