Java知识总结----事件处理机制(九)

      在上一篇文章中,跟大家介绍了队列的使用,在基于数据库的队列的是实现中,提到了可以使用事件处理机制类进行队列数据的处理。今天就来简单看看事件处理机制是怎么使用的。

      首先我们需要一个事件的实体类:Event

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 消息实体类
 */
public class Event {
	//消息体
	private Object data;
	//消息类型
	private Integer eventType;
	//重试次数
	private AtomicInteger tryCount = new AtomicInteger(0);
	//消息等待发送时间
	private long waitTime;
	//消息标识
	private String UUID;
	
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
	public Integer getEventType() {
		return eventType;
	}
	public void setEventType(Integer eventType) {
		this.eventType = eventType;
	}
	public AtomicInteger getTryCount() {
		return tryCount;
	}
	public void setTryCount(AtomicInteger tryCount) {
		this.tryCount = tryCount;
	}
	public long getWaitTime() {
		return waitTime;
	}
	public void setWaitTime(long waitTime) {
		this.waitTime = waitTime;
	}
	public String getUUID() {
		return UUID;
	}
	public void setUUID(String uUID) {
		UUID = uUID;
	}
	
}

接着是事件处理结果类:EventResult

import java.io.Serializable;

/**
 * 消息处理结果
 */
public class EventResult implements Serializable {
	private static final long serialVersionUID = 560051808572760660L;
	//是否成功
	private boolean isSuccess;
	//结果信息
	private String resultMsg;
	public boolean isSuccess() {
		return isSuccess;
	}
	
	public void setSuccess(boolean isSuccess) {
		this.isSuccess = isSuccess;
	}
	public String getResultMsg() {
		return resultMsg;
	}
	public void setResultMsg(String resultMsg) {
		this.resultMsg = resultMsg;
	}
	
}

对于事件来说,不同的事件类型可以有不同的事件处理类:基类:EventHandler,实现类:OneEventHandler

/**
 * 处理队列中的各种事件
 */
public interface EventHandler {
	/**
	 * 处理事件,返回处理结果
	 * @param event
	 */
	public EventResult handleEvent(final Event event);
}
import com.demo.event.Event;
import com.demo.event.EventHandler;
import com.demo.event.EventResult;

/**
 * 具体的事件处理类,根据不同的事件类型,可以有多种处理类
 */
public class OneEventHandler implements EventHandler {

	public EventResult handleEvent(Event event) {
		return null;
	}

}
下面,我们需要一个类来执行事件任务:EventWorker

import java.util.concurrent.Callable;

/**
 * 用于执行事件任务
 * @author lizhiyang
 *
 */
public class EventWorker implements Callable {

	//要处理的事件
	private Event event;
	//使用的事件处理器
	private EventHandler eventHandler;
	
	public EventWorker(Event event, EventHandler eventHandler) {
		this.event = event;
		this.eventHandler = eventHandler;
	}
	
	/**
	 * 调用事件处理器处理事件
	 */
	public EventResult call() throws Exception {
		if(event == null) {
			return null;
		}
		if(eventHandler == null) {
			return null;
		}
		EventResult eventResult = null;
		try {
			eventResult = eventHandler.handleEvent(event);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return eventResult;
	}

}
在事件处理的时候,需要有一个管理类,去添加事件:EventManager

import com.demo.event.Event;

public interface EventManager {

	/**
	 * 添加异步处理事件
	 * @param event
	 */
	public void addEvent(final Event event);
	/**
	 * 添加同步处理事件
	 * @param event
	 */
	public void addEventSyn(Event event);
}

分为两种,同时处理事件和异步处理事件,在第一次添加的时候都使用同步处理事件,如果时间处理失败或出现其他原因时,可以再次添加异步事件进行再次处理。

同步处理在EventMangerImpl中:

import java.util.Calendar;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.demo.event.Event;
import com.demo.event.EventHandler;
import com.demo.event.EventResult;
import com.demo.event.EventScheduled;
import com.demo.event.EventWorker;
import com.demo.event.handler.OneEventHandler;

public class EventManagerImpl implements EventManager {

private final static Logger logger = LoggerFactory.getLogger(EventManagerImpl.class);
	
	/**  开启队列调度线程 */
	private EventScheduled eventScheduled;
	
	/**  线程池管理 */
	/**
	 * spring 中的配置:
	 * 	                  
	              
	              
	              
	              
	              
	              
	              
	              
	                  
	                      
	                  
	              
     
	 */
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;
	
	/**
	 *  初始化异步调度线程
	 */
	public void init(){
		//构造调度任务
		eventScheduled = new EventScheduled();
		//启动调度线程
		eventScheduled.start();
	}

	/**
	 * 添加新的事件到队列中
	 * @param event
	 */
	public void addEvent(final Event event){
		if(!validateEvent(event)){
			if(logger.isDebugEnabled()){
			    logger.debug("addEvent event is illega");
			}
			return;
		}
		eventScheduled.addEvent(event);
	}
	
	public void addEventSyn(Event event) {
		if(!validateEvent(event)){
			if(logger.isDebugEnabled()){
			    logger.debug("addEventSyn event is illega");
			}
			return;
		}
		EventHandler eventHandle = new OneEventHandler();
		Future  future = null;
		try {
			future = threadPoolTaskExecutor.getThreadPoolExecutor().submit(new EventWorker(event,eventHandle));
			if(future != null) {
				EventResult eventResult = future.get();
				if(eventResult == null){
					if(logger.isDebugEnabled()){
						logger.debug("submit eventResult return null");
					}
					return;
				} 
				if(logger.isDebugEnabled()) {
					logger.debug("event submit :" + eventResult.toString());
				}
				//没有发送成功等待下次发送
				if(!eventResult.isSuccess()){
					// 暂时不用线程调度,因为缓存的问题
/*					int tryCount = event.getTryCount().intValue();
					event.setWaitTime(QueueRuleUtil.getNextConsumeSecond(tryCount,0));
					addEvent(event);*/
				} else {
					// 发送成功但是可能数据操作没有成功,或者是其他原因,对于这些数据采取线程调度处理,不需要马上处理
					event.setEventType(0);
					//一分钟后处理
					Calendar calendar = Calendar.getInstance();
					calendar.add(Calendar.MINUTE, 1);
					event.setWaitTime(calendar.getTime().getTime());
					addEvent(event);
				}
			}
		} catch (InterruptedException e) {
			logger.error(this.getClass() + "event submit Interrupted exception :",e);
			future.cancel(true);// 中断执行此任务的线程  
		} catch (ExecutionException e) {
			logger.error(this.getClass() + "event submit Execution exception:" ,e);
			 future.cancel(true);// 中断执行此任务的线程  
		}
	}
	
	/**
	 * 验证事件是否有效
	 * 
	 * @param event
	 * @return boolean
	 */
	private boolean validateEvent(Event event) {
		if (event == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("addEventSyn is must not be null");
			}
			return false;
		}
		if (StringUtils.isBlank(event.getUUID()) || event.getData() == null
				|| event.getEventType() == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("event request params is must not be null");
			}
			return false;
		}
		return true;
	}
		
	public void setThreadPoolTaskExecutor(
			ThreadPoolTaskExecutor threadPoolTaskExecutor) {
		this.threadPoolTaskExecutor = threadPoolTaskExecutor;
	}

}

异步处理时,需要有调度器进行处理:EventScheduled

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.demo.event.handler.OneEventHandler;

/**
 * 消息调度线程,主要用于消息的定时发送
 * 
 * 消息的异步处理过程
 *
 */
public class EventScheduled {
	
	private Logger logger = LoggerFactory.getLogger(EventScheduled.class);
	/**
	 * 调度线程池,用于重发数据
	 */
	private ScheduledExecutorService scheduledExecutorService;
	
	/**  采用无界队列	 */
	private final static ConcurrentLinkedQueue eventQueue = new ConcurrentLinkedQueue();
	
	/**
	 * 单个cpu的线程数
	 */
	private final int  POOL_SIZE = 5;
	
	 /**  队列监听等待时间 */
    private long waitTime = 200;
    
    /**
     * 添加异步事件
     * @param event
     */
    public void addEvent(Event event){
		if (event != null) {
			eventQueue.add(event);
		}
    }
    
    /**
     * 构造带不带缓存的客户端
     */
    public EventScheduled(){
    	//初始化ScheduledExecutorService 服务
		scheduledExecutorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);
    }
    
    
    /**
	 * 阻塞监听线程,只负责执行需要调度的消息
	 */
	public void start(){
		logger.info("EventScheduled start");
		new  Thread() {
			public void run() {
				while(true){
					try{
		            	CountDownLatch latch = new CountDownLatch(1);
		                latch.await(waitTime,TimeUnit.MILLISECONDS);
						Event event=eventQueue.poll();//线程安全
						if(event==null){
							continue;
						}
						//根据消息类型构造不同的事件处理类
						EventHandler eventHandle = new OneEventHandler();
						Future  future = null;
						try {
							future = scheduledExecutorService.schedule(new EventWorker(event,eventHandle), event.getWaitTime(), TimeUnit.SECONDS);
							if(future != null) {
								EventResult result = future.get();
								if(result == null){
									if(logger.isDebugEnabled()){
										logger.debug("event scheduled return null");
									}
									return;
								} 
								if(logger.isDebugEnabled()) {
									logger.debug("event scheduled :" + result.toString());
								}
							}
						} catch (InterruptedException e) {
							logger.error("event scheduled Interrupted exception :",e);
							 future.cancel(true);// 中断执行此任务的线程  
						} catch (ExecutionException e) {
							logger.error("event scheduled Execution exception:" ,e);
							 future.cancel(true);// 中断执行此任务的线程  
						}
					}catch(Throwable e){
						  logger.error("scheduled Exception:",e);
					}
				}
			}
		
		}.start();
	 }
}

以上就是事件处理机制的代码部分。对于事件处理机制来说,我本人的理解并不是特别的透彻,这里就不进行详细说明了,只是把示例代码贴出,仅供大家参考。


你可能感兴趣的:(Java知识总结)