diff --git a/pom.xml b/pom.xml
index 343450c..d53c137 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
cloud.tianai.captcha
tianai-captcha
- 1.0.alpha
+ 1.0.beta
tianai-captcha
滑块验证码
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java b/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java
new file mode 100644
index 0000000..4f07bf5
--- /dev/null
+++ b/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java
@@ -0,0 +1,115 @@
+package cloud.tianai.captcha.template.slider;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Slf4j
+public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
+
+ private final ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("slider-captcha-queue"));
+ private Queue queue;
+ private AtomicInteger pos = new AtomicInteger(0);
+ private SliderCaptchaTemplate target;
+ private int size;
+
+
+ public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, int size) {
+ this.target = target;
+ init(size);
+ }
+
+ private void init(int z) {
+ this.size = z;
+ this.pos = new AtomicInteger(0);
+ queue = new LinkedList<>();
+ // 初始化一个队列扫描
+ scheduledExecutor.scheduleAtFixedRate(() -> {
+ while (pos.get() < this.size) {
+ int count = pos.incrementAndGet();
+ if (count > size) {
+ return;
+ }
+ SliderCaptchaInfo slideImageInfo = target.getSlideImageInfo();
+ queue.add(slideImageInfo);
+ }
+ }, 0, 100, TimeUnit.MILLISECONDS);
+ }
+
+ @SneakyThrows
+ @Override
+ public SliderCaptchaInfo getSlideImageInfo() {
+ while (true) {
+ int i = pos.get();
+ if (i > 0) {
+ if (pos.compareAndSet(i, i - 1)) {
+ SliderCaptchaInfo poll = queue.poll();
+ if (poll != null) {
+ return poll;
+ }
+ }
+ }
+ // 休眠100毫秒
+ TimeUnit.MILLISECONDS.sleep(100);
+ }
+ }
+
+
+ public static void main(String[] args) throws InterruptedException {
+ SliderCaptchaTemplate captchaTemplate = new DefaultSliderCaptchaTemplate("webp", "webp", true);
+
+ captchaTemplate = new CacheSliderCaptchaTemplate(captchaTemplate, 20);
+ TimeUnit.SECONDS.sleep(5);
+ for (int i = 0; i < 100; i++) {
+ long start = System.currentTimeMillis();
+ SliderCaptchaInfo info = captchaTemplate.getSlideImageInfo();
+ long end = System.currentTimeMillis();
+ System.out.println("耗时:" + (end - start));
+ TimeUnit.MILLISECONDS.sleep(10);
+ }
+ }
+
+ @Override
+ public void addResource(URL url) {
+ target.addResource(url);
+ }
+
+ @Override
+ public void addTemplate(Map template) {
+ target.addTemplate(template);
+ }
+
+ @Override
+ public void setResource(List resources) {
+ target.setResource(resources);
+ }
+
+ @Override
+ public void setTemplates(List