场景:
在接收到一个请求或一个动作后,作消息延迟处理
spring配置(单例):
<bean id="umidOpService" class="com.alibaba.exodus2.biz.member.service.UmidOpServiceImpl" init-method="init">
<property name="waitTime" value="3001" />
</bean>
消息处理代码:
package com.wmmad.member.service;
import java.lang.ref.WeakReference;
import java.util.concurrent.LinkedBlockingQueue;
import com.alibaba.common.logging.Logger;
import com.alibaba.common.logging.LoggerFactory;
/**
*
*
* @author madding.lip at 2011.06.20
*/
public class UmidOpServiceImpl implements UmidOpService {
protected static final Logger logger = LoggerFactory.getLogger(UmidOpServiceImpl.class);
private CommandDispatcher commandFacade;
private long waitTime = 3000;
private final Queue queueOp = new Queue();
private final UmidSendThread umidThread = new UmidSendThread();
private LinkedBlockingQueue<LoginEvent> queue = new LinkedBlockingQueue<LoginEvent>();
WeakReference<LinkedBlockingQueue<LoginEvent>> wr = new WeakReference<LinkedBlockingQueue<LoginEvent>>(
queue);
// 代码初始化
public void init() {
umidThread.start();
if (logger.isInfoEnabled()) {
logger.info("thread started. tid: " + umidThread.getId());
}
}
public void addMessage(Object event) {
queueOp.produce(event);
if (logger.isInfoEnabled()) {
logger.info("produce a event/ all size is:" + queue.size());
}
}
public void afterPropertiesSet() throws Exception {
init();
}
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
private class UmidSendThread extends Thread {
public void run() {
while (true) {
synchronized (this) {
LoginEvent event = queueOp.consume();
long startTime = event.getGmtOccur().getTime();
long nowTime = System.currentTimeMillis();
long passTime = (nowTime - startTime);
if (logger.isInfoEnabled()) {
logger.info("begin[" + Thread.currentThread().getId() + "] " + "create time: " + startTime
+ " now: " + nowTime + " passTime: " + passTime + " leaveTime:"
+ (waitTime - passTime));
}
if (passTime < waitTime) {
try {
if (passTime > 0) {
Thread.sleep(waitTime - passTime);
} else {
Thread.sleep(waitTime);
}
} catch (InterruptedException e) {
logger.error(e);
}
}
nowTime = System.currentTimeMillis();
passTime = nowTime - startTime;
if (logger.isInfoEnabled()) {
logger.info("end[" + Thread.currentThread().getId() + "] " + "create time: " + startTime
+ " now: " + nowTime + " passTime: " + passTime + " leaveTime:"
+ (waitTime - passTime));
}
dealMessage(event);
if (logger.isInfoEnabled()) {
logger.info("consume a event/ all size is:" + queue.size());
}
}
}
}
}
private class Queue {
public synchronized void produce(LoginEvent event) {
wr.get().add(event);
this.notifyAll();
}
public synchronized LoginEvent consume() {
if (wr.get().isEmpty()) {
try {
this.wait();
} catch (InterruptedException e) {
logger.error(e);
}
}
return wr.get().poll();
}
}
@SuppressWarnings("unchecked")
public void dealMessage(LoginEvent event) {
.....
}
}
另一种实现(直接使用原生api):
class ConcurrentProducer implements Runnable {
@Override
public void run() {
int i = 0;
while (true) {
try {
queue.put(++i);
System.out.println("producer: " + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ConcurrentConsumer implements Runnable {
@Override
public void run() {
while (true) {
try {
System.out.println("consumer: " + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}