前言
在java开发的工作中是否会出现这样的场景,你需要实现一些异步运行的任务,该任务可能存在消耗大量内存的情况,所以需要对任务进行并发控制。如何优雅的实现并发控制呢?下面我会给大家介绍一个类——Semaphore,能很优雅的实现并发控制,继续往下看吧。
Semaphore介绍
首先我们看一下Semaphore类的构造函数是如何实现的。
public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); }
我们可以看到有两个参数,分别对应的是信号量的许可次数以及是否为公平锁,其中关于锁的概念可以参考补充。
我们看一下主要使用到的方法——tryAcquire,尝试申请锁,看一下该方法有几个实现。
public boolean tryAcquire() { return sync.nonfairTryAcquireShared(1) >= 0; } public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } public boolean tryAcquire(int permits) { if (permits < 0) throw new IllegalArgumentException(); return sync.nonfairTryAcquireShared(permits) >= 0; } public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { if (permits < 0) throw new IllegalArgumentException(); return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout)); }
我们需要注意的是,Semaphore是一个可重入的共享锁,所以除了可以增加申请锁的超时时间外,还可以设置申请的许可证数量。一般在业务场景中申请1次就可以了。
Semaphore还提供了阻塞的申请方式,一旦执行就会一直阻塞直到申请到锁,就是acquire方法。有兴趣的话,可以看看,也基本上支持多种参数实现。
代码演示
下面看一下我写的demo代码,演示一下Semaphore的限流效果。
先添加一些maven依赖
cn.hutool hutool-all 5.7.15 org.projectlombok lombok true
示例代码
package com.huyi.csdn.tools; import cn.hutool.core.thread.ThreadUtil; import lombok.Builder; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.concurrent.CustomizableThreadFactory; import java.util.Random; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.IntStream; /** * @Program: csdn @ClassName: SemaphoreDemo @Author: 剑客阿良_ALiang @Date: 2021-12-18 * 10:03 @Description: @Version: V1.0 */ @Slf4j public class SemaphoreDemo { private static final Semaphore SEMAPHORE = new Semaphore(3, true); private static final ExecutorService POOL = Executors.newFixedThreadPool(10, new CustomizableThreadFactory("TASK-")); private static final ScheduledExecutorService ENGINE_POOL = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("ENGINE-")); public static LinkedBlockingQueuetaskQueue; public static AtomicInteger codeBuilder; @Data @Builder public static class Task { private Integer code; private Runnable work; } public static void init() { taskQueue = new LinkedBlockingQueue<>(); codeBuilder = new AtomicInteger(0); log.info(">>> 任务队列初始化"); log.info(">>> 任务引擎启动"); engineOn(); } private static void engineOn() { ENGINE_POOL.scheduleAtFixedRate( () -> { if (taskQueue.isEmpty()) { log.info("队列为空,无任务需要执行"); } else { if (SEMAPHORE.tryAcquire()) { try { Task task = taskQueue.poll(); log.info("code:{} 任务获得执行许可", task.getCode()); POOL.submit(task.getWork()); log.info("code:{} 任务提交执行", task.getCode()); } catch (Exception exception) { exception.printStackTrace(); } } else { log.info("执行任务数量已经达到限制,无法执行任务"); } } }, 0, 1, TimeUnit.SECONDS); } public static void addTask(Runnable runnable) { Integer code = codeBuilder.incrementAndGet(); Task task = Task.builder() .code(code) .work( () -> { try { runnable.run(); } catch (Exception exception) { exception.printStackTrace(); } finally { log.info("code:{}-结束任务", code); SEMAPHORE.release(); } }) .build(); taskQueue.add(task); } public static void main(String[] args) { SemaphoreDemo.init(); Random random = new Random(); for (int i = 0; i < 10; i++) { SemaphoreDemo.addTask( () -> { IntStream.range(1, random.nextInt(10) + 1) .forEach( a -> { log.info("第{}次进攻敌方基地", a); ThreadUtil.sleep(1000); }); log.info("进攻结束"); }); } } }
代码说明:
1、先添加了两个静态的线程池,一个为给引擎工作的定时线程池,一个为给异步任务提供的任务线程池。
2、在初始化的时候会提前创建好任务队列,这里使用的是LinkedBlockingQueue。
3、初始化之后,可以引擎会定时尝试获取Semaphore的许可证,如果可以拿到则将任务提交给线程池执行。
4、在构建任务的时候,会将需要执行的内容重新包装,保证任务执行结束的时候会主动释放Semaphore的许可证。
5、main方法主要是在10秒内提交10个不定时完成的任务,我们可以看看是否限制了异步任务的数量。
验证一下,看看执行结果
E:\Java\jdk1.8.0_40\bin\java.exe "-javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar=3927:E:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\bin" -Dfile.encoding=UTF-8 -classpath E:\Java\jdk1.8.0_40\jre\lib\charsets.jar;E:\Java\jdk1.8.0_40\jre\lib\deploy.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\cldrdata.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\dnsns.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\jaccess.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\jfxrt.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\localedata.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\nashorn.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\sunec.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\sunmscapi.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk1.8.0_40\jre\lib\ext\zipfs.jar;E:\Java\jdk1.8.0_40\jre\lib\javaws.jar;E:\Java\jdk1.8.0_40\jre\lib\jce.jar;E:\Java\jdk1.8.0_40\jre\lib\jfr.jar;E:\Java\jdk1.8.0_40\jre\lib\jfxswt.jar;E:\Java\jdk1.8.0_40\jre\lib\jsse.jar;E:\Java\jdk1.8.0_40\jre\lib\management-agent.jar;E:\Java\jdk1.8.0_40\jre\lib\plugin.jar;E:\Java\jdk1.8.0_40\jre\lib\resources.jar;E:\Java\jdk1.8.0_40\jre\lib\rt.jar;C:\Users\yi\IdeaProjects\csdn\target\classes;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.5.6\spring-boot-starter-web-2.5.6.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-starter\2.5.6\spring-boot-starter-2.5.6.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.5.6\spring-boot-starter-logging-2.5.6.jar;C:\Users\yi\.m2\repository\ch\qos\logback\logback-classic\1.2.6\logback-classic-1.2.6.jar;C:\Users\yi\.m2\repository\ch\qos\logback\logback-core\1.2.6\logback-core-1.2.6.jar;C:\Users\yi\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;C:\Users\yi\.m2\repository\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;C:\Users\yi\.m2\repository\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;C:\Users\yi\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\yi\.m2\repository\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.5.6\spring-boot-starter-json-2.5.6.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.12.5\jackson-databind-2.12.5.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.12.5\jackson-annotations-2.12.5.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.12.5\jackson-core-2.12.5.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.5\jackson-datatype-jdk8-2.12.5.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.5\jackson-datatype-jsr310-2.12.5.jar;C:\Users\yi\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.5\jackson-module-parameter-names-2.12.5.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.5.6\spring-boot-starter-tomcat-2.5.6.jar;C:\Users\yi\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.54\tomcat-embed-core-9.0.54.jar;C:\Users\yi\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.54\tomcat-embed-el-9.0.54.jar;C:\Users\yi\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.54\tomcat-embed-websocket-9.0.54.jar;C:\Users\yi\.m2\repository\org\springframework\spring-web\5.3.12\spring-web-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-beans\5.3.12\spring-beans-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-webmvc\5.3.12\spring-webmvc-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-aop\5.3.12\spring-aop-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-context\5.3.12\spring-context-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-expression\5.3.12\spring-expression-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-devtools\2.5.6\spring-boot-devtools-2.5.6.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot\2.5.6\spring-boot-2.5.6.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.5.6\spring-boot-autoconfigure-2.5.6.jar;C:\Users\yi\.m2\repository\org\springframework\boot\spring-boot-configuration-processor\2.5.6\spring-boot-configuration-processor-2.5.6.jar;C:\Users\yi\.m2\repository\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;C:\Users\yi\.m2\repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;C:\Users\yi\.m2\repository\org\springframework\spring-core\5.3.12\spring-core-5.3.12.jar;C:\Users\yi\.m2\repository\org\springframework\spring-jcl\5.3.12\spring-jcl-5.3.12.jar;C:\Users\yi\.m2\repository\cn\hutool\hutool-all\5.7.15\hutool-all-5.7.15.jar;C:\Users\yi\.m2\repository\com\google\guava\guava\31.0.1-jre\guava-31.0.1-jre.jar;C:\Users\yi\.m2\repository\com\google\guava\failureaccess\1.0.1\failureaccess-1.0.1.jar;C:\Users\yi\.m2\repository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:\Users\yi\.m2\repository\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar;C:\Users\yi\.m2\repository\org\checkerframework\checker-qual\3.12.0\checker-qual-3.12.0.jar;C:\Users\yi\.m2\repository\com\google\errorprone\error_prone_annotations\2.7.1\error_prone_annotations-2.7.1.jar;C:\Users\yi\.m2\repository\com\google\j2objc\j2objc-annotations\1.3\j2objc-annotations-1.3.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacv-platform\1.5.5\javacv-platform-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacv\1.5.5\javacv-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2\0.2.0-1.5.5\libfreenect2-0.2.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\videoinput\0.200-1.5.5\videoinput-0.200-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\openjfx\javafx-graphics\11\javafx-graphics-11.jar;C:\Users\yi\.m2\repository\org\openjfx\javafx-graphics\11\javafx-graphics-11-win.jar;C:\Users\yi\.m2\repository\org\openjfx\javafx-base\11\javafx-base-11.jar;C:\Users\yi\.m2\repository\org\openjfx\javafx-base\11\javafx-base-11-win.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas-platform\0.3.13-1.5.5\openblas-platform-0.3.13-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp-platform\1.5.5\javacpp-platform-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-ios-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-ios-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-macosx-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\javacpp\1.5.5\javacpp-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-ios-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-ios-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\openblas\0.3.13-1.5.5\openblas-0.3.13-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv-platform\4.5.1-1.5.5\opencv-platform-4.5.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-ios-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-ios-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\opencv\4.5.1-1.5.5\opencv-4.5.1-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg-platform\4.3.2-1.5.5\ffmpeg-platform-4.3.2-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\ffmpeg\4.3.2-1.5.5\ffmpeg-4.3.2-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture-platform\2.13.3.31-1.5.5\flycapture-platform-2.13.3.31-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\flycapture\2.13.3.31-1.5.5\flycapture-2.13.3.31-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394-platform\2.2.6-1.5.5\libdc1394-platform-2.2.6-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\libdc1394\2.2.6-1.5.5\libdc1394-2.2.6-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect-platform\0.5.7-1.5.5\libfreenect-platform-0.5.7-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect\0.5.7-1.5.5\libfreenect-0.5.7-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2-platform\0.2.0-1.5.5\libfreenect2-platform-0.2.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2\0.2.0-1.5.5\libfreenect2-0.2.0-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2\0.2.0-1.5.5\libfreenect2-0.2.0-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2\0.2.0-1.5.5\libfreenect2-0.2.0-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\libfreenect2\0.2.0-1.5.5\libfreenect2-0.2.0-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense-platform\1.12.4-1.5.5\librealsense-platform-1.12.4-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense\1.12.4-1.5.5\librealsense-1.12.4-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2-platform\2.40.0-1.5.5\librealsense2-platform-2.40.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\librealsense2\2.40.0-1.5.5\librealsense2-2.40.0-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\videoinput-platform\0.200-1.5.5\videoinput-platform-0.200-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\videoinput\0.200-1.5.5\videoinput-0.200-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\videoinput\0.200-1.5.5\videoinput-0.200-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus-platform\2.3.1-1.5.5\artoolkitplus-platform-2.3.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\artoolkitplus\2.3.1-1.5.5\artoolkitplus-2.3.1-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark-platform\1.07-1.5.5\flandmark-platform-1.07-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\flandmark\1.07-1.5.5\flandmark-1.07-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica-platform\1.80.0-1.5.5\leptonica-platform-1.80.0-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\leptonica\1.80.0-1.5.5\leptonica-1.80.0-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract-platform\4.1.1-1.5.5\tesseract-platform-4.1.1-1.5.5.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-android-arm.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-android-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-android-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-android-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-linux-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-linux-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-linux-armhf.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-linux-arm64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-linux-ppc64le.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-macosx-x86_64.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-windows-x86.jar;C:\Users\yi\.m2\repository\org\bytedeco\tesseract\4.1.1-1.5.5\tesseract-4.1.1-1.5.5-windows-x86_64.jar;C:\Users\yi\.m2\repository\xyz\downgoon\snowflake\1.0.0\snowflake-1.0.0.jar com.huyi.csdn.tools.SemaphoreDemo 17:23:20.516 [main] INFO com.huyi.csdn.tools.SemaphoreDemo - >>> 任务队列初始化 17:23:20.519 [main] INFO com.huyi.csdn.tools.SemaphoreDemo - >>> 任务引擎启动 17:23:20.559 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:21.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1 任务获得执行许可 17:23:21.575 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1 任务提交执行 17:23:21.577 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:22.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2 任务获得执行许可 17:23:22.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2 任务提交执行 17:23:22.568 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:22.584 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:23.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3 任务获得执行许可 17:23:23.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3 任务提交执行 17:23:23.561 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:23.576 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:23.592 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:24.571 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:24.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:24.587 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:24.602 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:25.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:25.581 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:25.596 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:25.611 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次进攻敌方基地 17:23:26.570 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:26.584 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:26.600 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次进攻敌方基地 17:23:26.615 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:26.615 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1-结束任务 17:23:27.573 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4 任务获得执行许可 17:23:27.573 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4 任务提交执行 17:23:27.574 [TASK-4] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:27.574 [TASK-4] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4-结束任务 17:23:27.589 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:27.589 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3-结束任务 17:23:27.605 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第6次进攻敌方基地 17:23:28.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5 任务获得执行许可 17:23:28.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5 任务提交执行 17:23:28.571 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:28.618 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第7次进攻敌方基地 17:23:29.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6 任务获得执行许可 17:23:29.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6 任务提交执行 17:23:29.565 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:29.581 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:29.628 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:29.628 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2-结束任务 17:23:30.571 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:30.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7 任务获得执行许可 17:23:30.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7 任务提交执行 17:23:30.571 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:30.586 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:30.586 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5-结束任务 17:23:31.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8 任务获得执行许可 17:23:31.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8 任务提交执行 17:23:31.561 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:31.577 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:31.577 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:32.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:32.572 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次进攻敌方基地 17:23:32.587 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:32.587 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:33.564 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:33.581 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次进攻敌方基地 17:23:33.596 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:33.596 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次进攻敌方基地 17:23:34.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 执行任务数量已经达到限制,无法执行任务 17:23:34.592 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次进攻敌方基地 17:23:34.607 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次进攻敌方基地 17:23:34.607 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:34.607 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6-结束任务 17:23:35.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9 任务获得执行许可 17:23:35.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9 任务提交执行 17:23:35.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:35.602 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:35.602 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8-结束任务 17:23:35.617 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第6次进攻敌方基地 17:23:36.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10 任务获得执行许可 17:23:36.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:36.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9-结束任务 17:23:36.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10 任务提交执行 17:23:36.571 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次进攻敌方基地 17:23:36.617 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第7次进攻敌方基地 17:23:37.564 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:37.579 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:37.579 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10-结束任务 17:23:37.626 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第8次进攻敌方基地 17:23:38.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:38.630 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 进攻结束 17:23:38.630 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7-结束任务 17:23:39.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:40.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:41.567 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:42.562 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:43.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:44.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:45.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:46.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:47.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:48.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:49.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 17:23:50.570 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 队列为空,无任务需要执行 Process finished with exit code -1
可以看出,始终只有3个任务在执行任务。
补充
独占锁与共享锁
我发现很多人会把独占锁与公平锁搞混,其实他们不在一个方向上。
独占锁
独占锁是指在同一个时间只能有一个线程占有他,所以具备排他性。像synchronized关键字就是典型的独占锁。
举个栗子:独占锁相当于独间的澡堂,一个人进了这件澡堂,其他人都不能进,只有等他出来。
共享锁
什么是共享锁?
就是指同一时间可以被多个线程占有,像java自带的ReadWriteLock、Semaphore,他们可以设置自己共享的数量。
举个栗子:共享锁相当于一个大型公共澡堂,一开始就设定了能进去洗澡人的数量,比如是10个人,那么你要进去的时候会检查一下有没有满10个,满了你就在门口排队去吧。
公平锁与非公平锁
如果你在排队买奶茶,有个人插队了但是没人制止,你生不生气?他买到了奶茶扬长而去,这公不公平。
公平锁
公平锁就是多个线程去申请锁的使用权的时候,线程会直接进入队列排队,排在前面的可以先获得锁,排在后面的只能等着前面的先用。
举个栗子:有个澡堂,里面已经满了,后面的人想冲进去。但是有个保安站在门口,他让后面想进来的人都排好队,出来一个,就从队伍的前面放一个人进去。
没错,这就很公平。
但是公平锁也会带来其他的缺点,就是需要一个保安去控制,带来的其他开销。如果大家蜂拥而至去抢位置,少了这个保安,会更有效率。没错公平锁的缺点就是会带来更大的开销以及吞吐量下降。
非公平锁
与公平锁对应的就是非公平了,简而言之就是和公平锁反正来,什么不公平来什么。关键字synchronized就是典型的非公平锁。
缺点就是不公平,在某些场景中,特别是每次获取锁后会迅速执行并且释放锁的情况下,非公平锁是可以使用的。假设你洗澡的时间巨长,还有人插我队,这谁能忍得了?
可重入锁
可重入锁的概念很多人容易理解错,他是指同一个线程在申请到锁的情况下,继续申请锁不会阻塞,而是有个计数器记录该线程以及线程申请的次数。
举个栗子:还是单间浴室,但是我有一个洗澡卡,一旦我进了洗澡间就要刷卡,而且出来的时候还需要刷卡退出。那么我一旦进了洗澡间,我可以刷好几次进入卡,这不会阻塞住,因为都是我自己刷的。但是我退出洗澡间的时候我得刷同样次数的退出卡,不然下一个进来的人刷不了进入卡。好理解吗?你也别管我刷几次,反正我刷几次进入,就刷几次退出。
像java的关键字synchronized和ReentrantLock类都是可重入锁。
以上就是Java Semaphore实现高并发场景下的流量控制的详细内容,更多关于Java Semaphore流量控制的资料请关注脚本之家其它相关文章!