Java Semaphore实现高并发场景下的流量控制

Java Semaphore实现高并发场景下的流量控制

前言

在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依赖

        <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(">>> 任务队列初始化");
    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:Javajdk1.8.0_40injava.exe "-javaagent:E:Program FilesJetBrainsIntelliJ IDEA 2020.1.1libidea_rt.jar=3927:E:Program FilesJetBrainsIntelliJ IDEA 2020.1.1in" -Dfile.encoding=UTF-8 -classpath E:Javajdk1.8.0_40jrelibcharsets.jar;E:Javajdk1.8.0_40jrelibdeploy.jar;E:Javajdk1.8.0_40jrelibextaccess-bridge-64.jar;E:Javajdk1.8.0_40jrelibextcldrdata.jar;E:Javajdk1.8.0_40jrelibextdnsns.jar;E:Javajdk1.8.0_40jrelibextjaccess.jar;E:Javajdk1.8.0_40jrelibextjfxrt.jar;E:Javajdk1.8.0_40jrelibextlocaledata.jar;E:Javajdk1.8.0_40jrelibext
ashorn.jar;E:Javajdk1.8.0_40jrelibextsunec.jar;E:Javajdk1.8.0_40jrelibextsunjce_provider.jar;E:Javajdk1.8.0_40jrelibextsunmscapi.jar;E:Javajdk1.8.0_40jrelibextsunpkcs11.jar;E:Javajdk1.8.0_40jrelibextzipfs.jar;E:Javajdk1.8.0_40jrelibjavaws.jar;E:Javajdk1.8.0_40jrelibjce.jar;E:Javajdk1.8.0_40jrelibjfr.jar;E:Javajdk1.8.0_40jrelibjfxswt.jar;E:Javajdk1.8.0_40jrelibjsse.jar;E:Javajdk1.8.0_40jrelibmanagement-agent.jar;E:Javajdk1.8.0_40jrelibplugin.jar;E:Javajdk1.8.0_40jrelib
esources.jar;E:Javajdk1.8.0_40jrelib
t.jar;C:UsersyiIdeaProjectscsdn	argetclasses;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-starter-web2.5.6spring-boot-starter-web-2.5.6.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-starter2.5.6spring-boot-starter-2.5.6.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-starter-logging2.5.6spring-boot-starter-logging-2.5.6.jar;C:Usersyi.m2
epositorychqoslogbacklogback-classic1.2.6logback-classic-1.2.6.jar;C:Usersyi.m2
epositorychqoslogbacklogback-core1.2.6logback-core-1.2.6.jar;C:Usersyi.m2
epositoryorgapachelogginglog4jlog4j-to-slf4j2.14.1log4j-to-slf4j-2.14.1.jar;C:Usersyi.m2
epositoryorgapachelogginglog4jlog4j-api2.14.1log4j-api-2.14.1.jar;C:Usersyi.m2
epositoryorgslf4jjul-to-slf4j1.7.32jul-to-slf4j-1.7.32.jar;C:Usersyi.m2
epositoryjakartaannotationjakarta.annotation-api1.3.5jakarta.annotation-api-1.3.5.jar;C:Usersyi.m2
epositoryorgyamlsnakeyaml1.28snakeyaml-1.28.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-starter-json2.5.6spring-boot-starter-json-2.5.6.jar;C:Usersyi.m2
epositorycomfasterxmljacksoncorejackson-databind2.12.5jackson-databind-2.12.5.jar;C:Usersyi.m2
epositorycomfasterxmljacksoncorejackson-annotations2.12.5jackson-annotations-2.12.5.jar;C:Usersyi.m2
epositorycomfasterxmljacksoncorejackson-core2.12.5jackson-core-2.12.5.jar;C:Usersyi.m2
epositorycomfasterxmljacksondatatypejackson-datatype-jdk82.12.5jackson-datatype-jdk8-2.12.5.jar;C:Usersyi.m2
epositorycomfasterxmljacksondatatypejackson-datatype-jsr3102.12.5jackson-datatype-jsr310-2.12.5.jar;C:Usersyi.m2
epositorycomfasterxmljacksonmodulejackson-module-parameter-names2.12.5jackson-module-parameter-names-2.12.5.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-starter-tomcat2.5.6spring-boot-starter-tomcat-2.5.6.jar;C:Usersyi.m2
epositoryorgapache	omcatembed	omcat-embed-core9.0.54	omcat-embed-core-9.0.54.jar;C:Usersyi.m2
epositoryorgapache	omcatembed	omcat-embed-el9.0.54	omcat-embed-el-9.0.54.jar;C:Usersyi.m2
epositoryorgapache	omcatembed	omcat-embed-websocket9.0.54	omcat-embed-websocket-9.0.54.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-web5.3.12spring-web-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-beans5.3.12spring-beans-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-webmvc5.3.12spring-webmvc-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-aop5.3.12spring-aop-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-context5.3.12spring-context-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-expression5.3.12spring-expression-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-devtools2.5.6spring-boot-devtools-2.5.6.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot2.5.6spring-boot-2.5.6.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-autoconfigure2.5.6spring-boot-autoconfigure-2.5.6.jar;C:Usersyi.m2
epositoryorgspringframeworkootspring-boot-configuration-processor2.5.6spring-boot-configuration-processor-2.5.6.jar;C:Usersyi.m2
epositoryorgprojectlomboklombok1.18.22lombok-1.18.22.jar;C:Usersyi.m2
epositoryorgslf4jslf4j-api1.7.32slf4j-api-1.7.32.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-core5.3.12spring-core-5.3.12.jar;C:Usersyi.m2
epositoryorgspringframeworkspring-jcl5.3.12spring-jcl-5.3.12.jar;C:Usersyi.m2
epositorycnhutoolhutool-all5.7.15hutool-all-5.7.15.jar;C:Usersyi.m2
epositorycomgoogleguavaguava31.0.1-jreguava-31.0.1-jre.jar;C:Usersyi.m2
epositorycomgoogleguavafailureaccess1.0.1failureaccess-1.0.1.jar;C:Usersyi.m2
epositorycomgoogleguavalistenablefuture9999.0-empty-to-avoid-conflict-with-guavalistenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:Usersyi.m2
epositorycomgooglecodefindbugsjsr3053.0.2jsr305-3.0.2.jar;C:Usersyi.m2
epositoryorgcheckerframeworkchecker-qual3.12.0checker-qual-3.12.0.jar;C:Usersyi.m2
epositorycomgoogleerrorproneerror_prone_annotations2.7.1error_prone_annotations-2.7.1.jar;C:Usersyi.m2
epositorycomgooglej2objcj2objc-annotations1.3j2objc-annotations-1.3.jar;C:Usersyi.m2
epositoryorgytedecojavacv-platform1.5.5javacv-platform-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecojavacv1.5.5javacv-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2.2.0-1.5.5libfreenect2-0.2.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecovideoinput.200-1.5.5videoinput-0.200-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5.jar;C:Usersyi.m2
epositoryorgopenjfxjavafx-graphics11javafx-graphics-11.jar;C:Usersyi.m2
epositoryorgopenjfxjavafx-graphics11javafx-graphics-11-win.jar;C:Usersyi.m2
epositoryorgopenjfxjavafx-base11javafx-base-11.jar;C:Usersyi.m2
epositoryorgopenjfxjavafx-base11javafx-base-11-win.jar;C:Usersyi.m2
epositoryorgytedecoopenblas-platform.3.13-1.5.5openblas-platform-0.3.13-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecojavacpp-platform1.5.5javacpp-platform-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-ios-arm64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-ios-x86_64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-macosx-arm64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecojavacpp1.5.5javacpp-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-ios-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-ios-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoopenblas.3.13-1.5.5openblas-0.3.13-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopencv-platform4.5.1-1.5.5opencv-platform-4.5.1-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-ios-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-ios-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoopencv4.5.1-1.5.5opencv-4.5.1-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg-platform4.3.2-1.5.5ffmpeg-platform-4.3.2-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoffmpeg4.3.2-1.5.5ffmpeg-4.3.2-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflycapture-platform2.13.3.31-1.5.5flycapture-platform-2.13.3.31-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoflycapture2.13.3.31-1.5.5flycapture-2.13.3.31-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibdc1394-platform2.2.6-1.5.5libdc1394-platform-2.2.6-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecolibdc13942.2.6-1.5.5libdc1394-2.2.6-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect-platform.5.7-1.5.5libfreenect-platform-0.5.7-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect.5.7-1.5.5libfreenect-0.5.7-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2-platform.2.0-1.5.5libfreenect2-platform-0.2.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2.2.0-1.5.5libfreenect2-0.2.0-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2.2.0-1.5.5libfreenect2-0.2.0-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2.2.0-1.5.5libfreenect2-0.2.0-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibfreenect2.2.0-1.5.5libfreenect2-0.2.0-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense-platform1.12.4-1.5.5librealsense-platform-1.12.4-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense1.12.4-1.5.5librealsense-1.12.4-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense2-platform2.40.0-1.5.5librealsense2-platform-2.40.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecolibrealsense22.40.0-1.5.5librealsense2-2.40.0-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecovideoinput-platform.200-1.5.5videoinput-platform-0.200-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecovideoinput.200-1.5.5videoinput-0.200-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecovideoinput.200-1.5.5videoinput-0.200-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus-platform2.3.1-1.5.5artoolkitplus-platform-2.3.1-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoartoolkitplus2.3.1-1.5.5artoolkitplus-2.3.1-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark-platform1.07-1.5.5flandmark-platform-1.07-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoflandmark1.07-1.5.5flandmark-1.07-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica-platform1.80.0-1.5.5leptonica-platform-1.80.0-1.5.5.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedecoleptonica1.80.0-1.5.5leptonica-1.80.0-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract-platform4.1.1-1.5.5	esseract-platform-4.1.1-1.5.5.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-android-arm.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-android-arm64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-android-x86.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-android-x86_64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-linux-x86.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-linux-x86_64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-linux-armhf.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-linux-arm64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-linux-ppc64le.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-macosx-x86_64.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-windows-x86.jar;C:Usersyi.m2
epositoryorgytedeco	esseract4.1.1-1.5.5	esseract-4.1.1-1.5.5-windows-x86_64.jar;C:Usersyi.m2
epositoryxyzdowngoonsnowflake1.0.0snowflake-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流量控制的资料请关注云海天教程其它相关文章!