package com.github.shansun.sparrow.actor.internal; import com.github.shansun.sparrow.actor.api.MessageQueue; import com.github.shansun.sparrow.actor.api.MessageRedcapCallback; import com.github.shansun.sparrow.actor.statistic.Statistics; import org.slf4j.LoggerFactory; import com.github.shansun.sparrow.actor.statistic.CountStatistic; /** * 消息的搬运工,负责把消息取出来,丢给指定的Actor去处理 * * @author: lanbo <br> * @version: 1.0 <br> * @date: 2012-7-20 */ public class MessageRedcapRunnable implements Runnable { private boolean running; final MessageQueue<MessageWrapper> queue; final MessageRedcapCallback callback; long maximumSize = 0; Thread thisThread = Thread.currentThread(); volatile Object lock = new Object(); CountStatistic stat; public MessageRedcapRunnable(MessageRedcapCallback callback) { this(0, callback); } public MessageRedcapRunnable(MessageRedcapCallback callback, MessageQueue<MessageWrapper> msgQueue) { this(0, callback, null); } public MessageRedcapRunnable(long maximumSize, MessageRedcapCallback callback) { this(maximumSize, callback, null); } public MessageRedcapRunnable(long maximumSize, MessageRedcapCallback callback, MessageQueue<MessageWrapper> msgQueue) { super(); // 初始化后即允许执行线程逻辑 setRunning(true); // 初始化本线程私有的消息队列 queue = msgQueue == null ? new MemMessageQueue() : msgQueue; // 真正的业务逻辑,由外部去实现,一般放到Manager里 this.callback = callback; } /** * 添加消息 * * @param wrapper */ public boolean addMessage(MessageWrapper wrapper) { if (maximumSize > 0 && maximumSize <= queue.size()) { return false; } queue.add(wrapper); synchronized (lock) { lock.notify(); } return true; } @Override public void run() { stat = Statistics.getCountStat(Thread.currentThread().getName() + "-Processed"); thisThread = Thread.currentThread(); synchronized (lock) { while (isRunning()) { MessageWrapper message = (MessageWrapper) queue.poll(); if (message == null) { try { LoggerFactory.getLogger(getClass()).info("[" + Thread.currentThread().getName() + "] is idle, there is no message."); lock.wait(); } catch (InterruptedException e) { LoggerFactory.getLogger(getClass()).warn("Thread sleep was interrupted", e); } continue; } else { try { // 处理消息 callback.execute(message); LoggerFactory.getLogger(getClass()).info("processing message [" + message + "]"); } catch (Throwable e) { LoggerFactory.getLogger(getClass()).warn("processing message encounter error", e); } finally { stat.incr(); } } } } processLeftMessage(); } /** * 处理掉剩余的消息 */ private void processLeftMessage() { MessageWrapper msg = null; while ((msg = queue.poll()) != null) { callback.execute(msg); } } public boolean isRunning() { return running; } public MessageQueue<MessageWrapper> getQueue() { return queue; } public MessageRedcapCallback getCallback() { return callback; } public long getMaximumSize() { return maximumSize; } public void setRunning(boolean running) { this.running = running; } }