package com.hundsun.jresplus.web.nosession; import java.util.concurrent.BlockingQueue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import com.hundsun.jresplus.common.util.BlockingQueueLocate; /** * @author LeoHu copy by sagahl copy by fish * */ public class UUIDPoolGenerator implements UUIDGenerator, InitializingBean, DisposableBean { private static final Logger logger = LoggerFactory .getLogger(UUIDPoolGenerator.class); private static final String EventStringPlaceholder = "esp"; private Lock lock = new ReentrantLock(); private Condition worker = lock.newCondition(); private BlockingQueue<String> queue = BlockingQueueLocate .createBlockingQueue(); private Thread producer; private boolean fixedLength = false; private int capacity = 1000; private int threshold = 200; public void afterPropertiesSet() throws Exception { if (threshold > capacity) { throw new IllegalArgumentException( "threshold can't great than capacity."); } producer = new Thread("UUIDGen") { @Override public void run() { int times = capacity / threshold; for (int i = 0; i < times; i++) { produce(); } logger.debug("fill the queue with capacity:" + capacity); while (!Thread.interrupted()) { lock.lock(); try { worker.await(); produce(); } catch (InterruptedException e) { break; } finally { lock.unlock(); } } } }; producer.setDaemon(true); producer.start(); } public void destroy() throws Exception { producer.interrupt(); } private void produce() { for (int i = 0; i < threshold; i++) { queue.add(fixedLength ? RandomShortUUID.getFixSize() : RandomShortUUID.get()); } queue.add(EventStringPlaceholder); } private void startProduce() { lock.lock(); try { worker.signal(); } finally { lock.unlock(); } } public String gain() { String one; try { one = queue.take(); } catch (InterruptedException e) { throw new RuntimeException(e); } if (one != EventStringPlaceholder) { return one; } startProduce(); return gain(); } }