Java Semaphore實(shí)現(xiàn)高并發(fā)場(chǎng)景下的流量控制
前言
在java開(kāi)發(fā)的工作中是否會(huì)出現(xiàn)這樣的場(chǎng)景,你需要實(shí)現(xiàn)一些異步運(yùn)行的任務(wù),該任務(wù)可能存在消耗大量?jī)?nèi)存的情況,所以需要對(duì)任務(wù)進(jìn)行并發(fā)控制。如何優(yōu)雅的實(shí)現(xiàn)并發(fā)控制呢?下面我會(huì)給大家介紹一個(gè)類——Semaphore,能很優(yōu)雅的實(shí)現(xiàn)并發(fā)控制,繼續(xù)往下看吧。
Semaphore介紹
首先我們看一下Semaphore類的構(gòu)造函數(shù)是如何實(shí)現(xiàn)的。
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
我們可以看到有兩個(gè)參數(shù),分別對(duì)應(yīng)的是信號(hào)量的許可次數(shù)以及是否為公平鎖,其中關(guān)于鎖的概念可以參考補(bǔ)充。
我們看一下主要使用到的方法——tryAcquire,嘗試申請(qǐng)鎖,看一下該方法有幾個(gè)實(shí)現(xiàn)。
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是一個(gè)可重入的共享鎖,所以除了可以增加申請(qǐng)鎖的超時(shí)時(shí)間外,還可以設(shè)置申請(qǐng)的許可證數(shù)量。一般在業(yè)務(wù)場(chǎng)景中申請(qǐng)1次就可以了。
Semaphore還提供了阻塞的申請(qǐng)方式,一旦執(zhí)行就會(huì)一直阻塞直到申請(qǐng)到鎖,就是acquire方法。有興趣的話,可以看看,也基本上支持多種參數(shù)實(shí)現(xiàn)。
代碼演示
下面看一下我寫的demo代碼,演示一下Semaphore的限流效果。
先添加一些maven依賴
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.15</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
示例代碼
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 LinkedBlockingQueue<Task> taskQueue;
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(">>> 任務(wù)隊(duì)列初始化");
log.info(">>> 任務(wù)引擎啟動(dòng)");
engineOn();
}
private static void engineOn() {
ENGINE_POOL.scheduleAtFixedRate(
() -> {
if (taskQueue.isEmpty()) {
log.info("隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行");
} else {
if (SEMAPHORE.tryAcquire()) {
try {
Task task = taskQueue.poll();
log.info("code:{} 任務(wù)獲得執(zhí)行許可", task.getCode());
POOL.submit(task.getWork());
log.info("code:{} 任務(wù)提交執(zhí)行", task.getCode());
} catch (Exception exception) {
exception.printStackTrace();
}
} else {
log.info("執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù)");
}
}
},
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:{}-結(jié)束任務(wù)", 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("第{}次進(jìn)攻敵方基地", a);
ThreadUtil.sleep(1000);
});
log.info("進(jìn)攻結(jié)束");
});
}
}
}
代碼說(shuō)明:
1、先添加了兩個(gè)靜態(tài)的線程池,一個(gè)為給引擎工作的定時(shí)線程池,一個(gè)為給異步任務(wù)提供的任務(wù)線程池。
2、在初始化的時(shí)候會(huì)提前創(chuàng)建好任務(wù)隊(duì)列,這里使用的是LinkedBlockingQueue。
3、初始化之后,可以引擎會(huì)定時(shí)嘗試獲取Semaphore的許可證,如果可以拿到則將任務(wù)提交給線程池執(zhí)行。
4、在構(gòu)建任務(wù)的時(shí)候,會(huì)將需要執(zhí)行的內(nèi)容重新包裝,保證任務(wù)執(zhí)行結(jié)束的時(shí)候會(huì)主動(dòng)釋放Semaphore的許可證。
5、main方法主要是在10秒內(nèi)提交10個(gè)不定時(shí)完成的任務(wù),我們可以看看是否限制了異步任務(wù)的數(shù)量。
驗(yàn)證一下,看看執(zhí)行結(jié)果
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 - >>> 任務(wù)隊(duì)列初始化 17:23:20.519 [main] INFO com.huyi.csdn.tools.SemaphoreDemo - >>> 任務(wù)引擎啟動(dòng) 17:23:20.559 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:21.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1 任務(wù)獲得執(zhí)行許可 17:23:21.575 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1 任務(wù)提交執(zhí)行 17:23:21.577 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:22.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2 任務(wù)獲得執(zhí)行許可 17:23:22.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2 任務(wù)提交執(zhí)行 17:23:22.568 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:22.584 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:23.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3 任務(wù)獲得執(zhí)行許可 17:23:23.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3 任務(wù)提交執(zhí)行 17:23:23.561 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:23.576 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:23.592 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:24.571 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:24.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:24.587 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:24.602 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:25.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:25.581 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:25.596 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:25.611 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次進(jìn)攻敵方基地 17:23:26.570 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:26.584 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:26.600 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次進(jìn)攻敵方基地 17:23:26.615 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:26.615 [TASK-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:1-結(jié)束任務(wù) 17:23:27.573 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4 任務(wù)獲得執(zhí)行許可 17:23:27.573 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4 任務(wù)提交執(zhí)行 17:23:27.574 [TASK-4] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:27.574 [TASK-4] INFO com.huyi.csdn.tools.SemaphoreDemo - code:4-結(jié)束任務(wù) 17:23:27.589 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:27.589 [TASK-3] INFO com.huyi.csdn.tools.SemaphoreDemo - code:3-結(jié)束任務(wù) 17:23:27.605 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第6次進(jìn)攻敵方基地 17:23:28.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5 任務(wù)獲得執(zhí)行許可 17:23:28.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5 任務(wù)提交執(zhí)行 17:23:28.571 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:28.618 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 第7次進(jìn)攻敵方基地 17:23:29.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6 任務(wù)獲得執(zhí)行許可 17:23:29.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6 任務(wù)提交執(zhí)行 17:23:29.565 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:29.581 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:29.628 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:29.628 [TASK-2] INFO com.huyi.csdn.tools.SemaphoreDemo - code:2-結(jié)束任務(wù) 17:23:30.571 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:30.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7 任務(wù)獲得執(zhí)行許可 17:23:30.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7 任務(wù)提交執(zhí)行 17:23:30.571 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:30.586 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:30.586 [TASK-5] INFO com.huyi.csdn.tools.SemaphoreDemo - code:5-結(jié)束任務(wù) 17:23:31.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8 任務(wù)獲得執(zhí)行許可 17:23:31.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8 任務(wù)提交執(zhí)行 17:23:31.561 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:31.577 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:31.577 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:32.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:32.572 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第2次進(jìn)攻敵方基地 17:23:32.587 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:32.587 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:33.564 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:33.581 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第3次進(jìn)攻敵方基地 17:23:33.596 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:33.596 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次進(jìn)攻敵方基地 17:23:34.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 執(zhí)行任務(wù)數(shù)量已經(jīng)達(dá)到限制,無(wú)法執(zhí)行任務(wù) 17:23:34.592 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 第4次進(jìn)攻敵方基地 17:23:34.607 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第5次進(jìn)攻敵方基地 17:23:34.607 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:34.607 [TASK-6] INFO com.huyi.csdn.tools.SemaphoreDemo - code:6-結(jié)束任務(wù) 17:23:35.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9 任務(wù)獲得執(zhí)行許可 17:23:35.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9 任務(wù)提交執(zhí)行 17:23:35.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:35.602 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:35.602 [TASK-8] INFO com.huyi.csdn.tools.SemaphoreDemo - code:8-結(jié)束任務(wù) 17:23:35.617 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第6次進(jìn)攻敵方基地 17:23:36.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10 任務(wù)獲得執(zhí)行許可 17:23:36.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:36.571 [TASK-9] INFO com.huyi.csdn.tools.SemaphoreDemo - code:9-結(jié)束任務(wù) 17:23:36.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10 任務(wù)提交執(zhí)行 17:23:36.571 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - 第1次進(jìn)攻敵方基地 17:23:36.617 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第7次進(jìn)攻敵方基地 17:23:37.564 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:37.579 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:37.579 [TASK-10] INFO com.huyi.csdn.tools.SemaphoreDemo - code:10-結(jié)束任務(wù) 17:23:37.626 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 第8次進(jìn)攻敵方基地 17:23:38.568 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:38.630 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - 進(jìn)攻結(jié)束 17:23:38.630 [TASK-7] INFO com.huyi.csdn.tools.SemaphoreDemo - code:7-結(jié)束任務(wù) 17:23:39.565 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:40.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:41.567 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:42.562 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:43.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:44.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:45.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:46.563 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:47.571 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:48.561 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:49.572 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 17:23:50.570 [ENGINE-1] INFO com.huyi.csdn.tools.SemaphoreDemo - 隊(duì)列為空,無(wú)任務(wù)需要執(zhí)行 Process finished with exit code -1
可以看出,始終只有3個(gè)任務(wù)在執(zhí)行任務(wù)。
補(bǔ)充
獨(dú)占鎖與共享鎖
我發(fā)現(xiàn)很多人會(huì)把獨(dú)占鎖與公平鎖搞混,其實(shí)他們不在一個(gè)方向上。
獨(dú)占鎖
獨(dú)占鎖是指在同一個(gè)時(shí)間只能有一個(gè)線程占有他,所以具備排他性。像synchronized關(guān)鍵字就是典型的獨(dú)占鎖。
舉個(gè)栗子:獨(dú)占鎖相當(dāng)于獨(dú)間的澡堂,一個(gè)人進(jìn)了這件澡堂,其他人都不能進(jìn),只有等他出來(lái)。
共享鎖
什么是共享鎖?
就是指同一時(shí)間可以被多個(gè)線程占有,像java自帶的ReadWriteLock、Semaphore,他們可以設(shè)置自己共享的數(shù)量。
舉個(gè)栗子:共享鎖相當(dāng)于一個(gè)大型公共澡堂,一開(kāi)始就設(shè)定了能進(jìn)去洗澡人的數(shù)量,比如是10個(gè)人,那么你要進(jìn)去的時(shí)候會(huì)檢查一下有沒(méi)有滿10個(gè),滿了你就在門口排隊(duì)去吧。
公平鎖與非公平鎖
如果你在排隊(duì)買奶茶,有個(gè)人插隊(duì)了但是沒(méi)人制止,你生不生氣?他買到了奶茶揚(yáng)長(zhǎng)而去,這公不公平。
公平鎖
公平鎖就是多個(gè)線程去申請(qǐng)鎖的使用權(quán)的時(shí)候,線程會(huì)直接進(jìn)入隊(duì)列排隊(duì),排在前面的可以先獲得鎖,排在后面的只能等著前面的先用。
舉個(gè)栗子:有個(gè)澡堂,里面已經(jīng)滿了,后面的人想沖進(jìn)去。但是有個(gè)保安站在門口,他讓后面想進(jìn)來(lái)的人都排好隊(duì),出來(lái)一個(gè),就從隊(duì)伍的前面放一個(gè)人進(jìn)去。
沒(méi)錯(cuò),這就很公平。
但是公平鎖也會(huì)帶來(lái)其他的缺點(diǎn),就是需要一個(gè)保安去控制,帶來(lái)的其他開(kāi)銷。如果大家蜂擁而至去搶位置,少了這個(gè)保安,會(huì)更有效率。沒(méi)錯(cuò)公平鎖的缺點(diǎn)就是會(huì)帶來(lái)更大的開(kāi)銷以及吞吐量下降。
非公平鎖
與公平鎖對(duì)應(yīng)的就是非公平了,簡(jiǎn)而言之就是和公平鎖反正來(lái),什么不公平來(lái)什么。關(guān)鍵字synchronized就是典型的非公平鎖。
缺點(diǎn)就是不公平,在某些場(chǎng)景中,特別是每次獲取鎖后會(huì)迅速執(zhí)行并且釋放鎖的情況下,非公平鎖是可以使用的。假設(shè)你洗澡的時(shí)間巨長(zhǎng),還有人插我隊(duì),這誰(shuí)能忍得了?
可重入鎖
可重入鎖的概念很多人容易理解錯(cuò),他是指同一個(gè)線程在申請(qǐng)到鎖的情況下,繼續(xù)申請(qǐng)鎖不會(huì)阻塞,而是有個(gè)計(jì)數(shù)器記錄該線程以及線程申請(qǐng)的次數(shù)。
舉個(gè)栗子:還是單間浴室,但是我有一個(gè)洗澡卡,一旦我進(jìn)了洗澡間就要刷卡,而且出來(lái)的時(shí)候還需要刷卡退出。那么我一旦進(jìn)了洗澡間,我可以刷好幾次進(jìn)入卡,這不會(huì)阻塞住,因?yàn)槎际俏易约核⒌?。但是我退出洗澡間的時(shí)候我得刷同樣次數(shù)的退出卡,不然下一個(gè)進(jìn)來(lái)的人刷不了進(jìn)入卡。好理解嗎?你也別管我刷幾次,反正我刷幾次進(jìn)入,就刷幾次退出。
像java的關(guān)鍵字synchronized和ReentrantLock類都是可重入鎖。
以上就是Java Semaphore實(shí)現(xiàn)高并發(fā)場(chǎng)景下的流量控制的詳細(xì)內(nèi)容,更多關(guān)于Java Semaphore流量控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)好用的MybatisPlus代碼生成器
這篇文章主要介紹了Java實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)好用的MybatisPlus代碼生成器,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
細(xì)說(shuō)Springcloud eureka的幾種主動(dòng)下線服務(wù)的方式
這篇文章主要介紹了細(xì)說(shuō)Springcloud eureka的幾種主動(dòng)下線服務(wù)的方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA
這篇文章主要介紹了關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA的問(wèn)題,文中提供了詳細(xì)的圖文講解,需要的朋友可以參考下,如果有錯(cuò)誤的地方還請(qǐng)指正2023-03-03
解決使用@RequestParam注解和泛型遇到的問(wèn)題
這篇文章主要介紹了解決使用@RequestParam注解和泛型遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Mybatis Limit實(shí)現(xiàn)分頁(yè)功能
這篇文章主要介紹了Mybatis Limit實(shí)現(xiàn)分頁(yè)功能,使用Limit實(shí)現(xiàn)分頁(yè)可以減少數(shù)據(jù)的處理量,本文通過(guò)代碼講解的非常詳細(xì),需要的朋友可以參考下2021-04-04
SpringCloud Zuul過(guò)濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例
這篇文章主要介紹了SpringCloud Zuul過(guò)濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Java項(xiàng)目實(shí)現(xiàn)尋找迷宮出路
這篇文章主要為大家詳細(xì)介紹了Java項(xiàng)目實(shí)現(xiàn)尋找迷宮出路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
java時(shí)間段查詢將00:00:00更換成23:59:59
本文主要介紹了java時(shí)間段查詢將00:00:00更換成23:59:59,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01

