package com.sissi.looper.impl; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sissi.commons.Trace; import com.sissi.feed.Feeder; import com.sissi.looper.LooperBuilder; import com.sissi.resource.ResourceCounter; import com.sissi.thread.Runner; import com.sissi.thread.impl.ExecuteInterval; /** * 私有Loop策略,每个Loop独享私有线程 * * @author kim 2013-10-30 */ public class PersonalLooperBuilder implements LooperBuilder { private final Log log = LogFactory.getLog(this.getClass()); private final String resource = PersonalLooper.class.getSimpleName(); private final ResourceCounter resourceCounter; private final ExecuteInterval interval; private final Runner runner; private final int threadNum; /** * @param runner * @param interval 堵塞时间 * @param threadNum 线程数量 * @param resourceCounter */ public PersonalLooperBuilder(Runner runner, ExecuteInterval interval, int threadNum, ResourceCounter resourceCounter) { super(); this.runner = runner; this.interval = interval; this.threadNum = threadNum; this.resourceCounter = resourceCounter; } @Override public PersonalLooper build(Future<?> future, Feeder feeder) { return new PersonalLooper(future, feeder); } private class PersonalLooper extends FeedLooper implements Runnable { private final AtomicBoolean state = new AtomicBoolean(); private PersonalLooper(Future<?> future, Feeder feeder) { super(PersonalLooperBuilder.this.interval, future, feeder); } @Override public void run() { // 私有Loop开启计数 PersonalLooperBuilder.this.resourceCounter.increment(PersonalLooperBuilder.this.resource); while (true) { try { if (this.prepareStop()) { break; } super.getAndFeed(); } catch (Exception e) { PersonalLooperBuilder.this.log.warn(e.toString()); Trace.trace(PersonalLooperBuilder.this.log, e); } } // 私有Loop关闭计数 PersonalLooperBuilder.this.resourceCounter.decrement(PersonalLooperBuilder.this.resource); } /** * 是否关闭私有Loop * * @return */ private boolean prepareStop() { return this.state.get() == false; } /* * 开启指定线程数量的私有Loop * * @see com.sissi.looper.Looper#start() */ @Override public PersonalLooper start() { this.state.set(true); PersonalLooperBuilder.this.runner.executor(PersonalLooperBuilder.this.threadNum, this); return this; } /* * 关闭所有关联此私有Loop的线程, 如果线程正在堵塞则Interval间隔后关闭 * * @see com.sissi.looper.Looper#stop() */ @Override public PersonalLooper stop() { this.state.set(false); return this; } } }