Java的newSingleThreadExecutor似乎创建了许多线程。

huangapple 未分类评论55阅读模式
英文:

Java newSingleThreadExecutor seems to create many threads

问题

我有一个任务,由于它需要大量资源,我想以异步方式执行它,因此我想要一个单线程执行器池,在第一个任务完成后将启动下一个任务。

通过我的主应用程序线程,我可能会多次调用此任务。

我编写了一个简单的测试,我发现不是每隔5秒钟(我设置的人为延迟)调用一次单个线程,而是被多次调用。

这是我的类:

public class NoTypeHandlerService {

    private Executor pool;

    private static NoTypeHandlerService instance = null;

    @Getter
    private int SECONDS_TO_WAIT_BETWEEN_JOBS = 5;

    private NoTypeHandlerService() {
        pool = Executors.newSingleThreadExecutor();
    }

    public static NoTypeHandlerService getInstance() {
        if (instance == null) {
            instance = new NoTypeHandlerService();
        }
        return instance;
    }

    public void assignType(ComplianceCandidate candidate) {
        CompletableFuture.supplyAsync(() -> candidate, pool).thenApplyAsync(AssignType::doWork);
    }
}

AssignType 类是任务:

public class AssignType {

    public static ComplianceCandidate doWork(ComplianceCandidate candidate) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            log.error("Could not execute type assignation job for: {}", candidate);
        }
        log.debug("Proceeding to assign type for: {}", candidate);

        return candidate;
    }
}

这是我的简单测试类:

@Test
@DisplayName("Creates fake candidates and make type service")
public void testTypeAssignationTest() throws InterruptedException {
    ComplianceDevice device = new ComplianceDevice("0X123456", "99.6.6.1", 1, 1);
    ComplianceDevice device1 = new ComplianceDevice("0X1234567", "99.6.6.1", 1, 1);
    ComplianceDevice device2 = new ComplianceDevice("0X12345678", "99.6.6.1", 1, 1);
    ComplianceCandidate candidate = new ComplianceCandidate(device);
    ComplianceCandidate candidate1 = new ComplianceCandidate(device1);
    ComplianceCandidate candidate2 = new ComplianceCandidate(device2);
    NoTypeHandlerService.getInstance().assignType(candidate);
    NoTypeHandlerService.getInstance().assignType(candidate1);
    NoTypeHandlerService.getInstance().assignType(candidate2);
    log.debug("Successfully entered all jobs to execution");

    TimeUnit.SECONDS.sleep(15);
}

当我运行这个测试时,我看到以下日志:

2020-07-26 21:36:50 [main] - Successfully entered all jobs to execution
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-7] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X12345678, type=null]]
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-5] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X1234567, type=null]]
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-3] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X123456, type=null]]

这不是我期望的行为,虽然主线程确实没有被阻塞,但是我并没有看到只有一个 ForkJoinPool.commonPool-worker-7 每隔5秒打印一次,我看到3个都在同一时间打印。

英文:

I have a task that i want to do in an async manner since its resource intensive, therefore i want a single thread executor pool that will start the next task once the first one is completed

through my main application thread i might call this task numerous times

i wrote a simple test and I'm seeing that instead of a single thread being called every 5 seconds (the artificial delay i placed to simulate), its being called many times

here is my class

public class NoTypeHandlerService {


    private Executor pool;

    private static NoTypeHandlerService instance = null;

    @Getter
    private int SECONDS_TO_WAIT_BETWEEN_JOBS = 5;

    private NoTypeHandlerService() {
        pool = Executors.newSingleThreadExecutor();

    }

    public static NoTypeHandlerService getInstance() {
        if (instance == null) {
            instance = new NoTypeHandlerService();
        }
        return instance;
    }

    public void assignType(ComplianceCandidate candidate) {

        CompletableFuture.supplyAsync(()-> candidate, pool).thenApplyAsync(AssignType::doWork);
    }

}

AssignType class is the task

public class AssignType {

    public static ComplianceCandidate doWork(ComplianceCandidate candidate) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            log.error("Could not execute type assignation job for: {}", candidate);
        }
        log.debug("Proceeding to assign type for: {}", candidate);

        return candidate;

    }
    
}

here is my simple test class

   @Test
    @DisplayName("Creates fake candidates and make type service")
    public void testTypeAssignationTest() throws InterruptedException {
        ComplianceDevice device = new ComplianceDevice("0X123456", "99.6.6.1", 1, 1);
        ComplianceDevice device1 = new ComplianceDevice("0X1234567", "99.6.6.1", 1, 1);
        ComplianceDevice device2 = new ComplianceDevice("0X12345678", "99.6.6.1", 1, 1);
        ComplianceCandidate candidate = new ComplianceCandidate(device);
        ComplianceCandidate candidate1 = new ComplianceCandidate(device1);
        ComplianceCandidate candidate2 = new ComplianceCandidate(device2);
        NoTypeHandlerService.getInstance().assignType(candidate);
        NoTypeHandlerService.getInstance().assignType(candidate1);
        NoTypeHandlerService.getInstance().assignType(candidate2);
        log.debug("Successfully entered all jobs to execution");

        TimeUnit.SECONDS.sleep(15);

    }

when i run this i see the following logs

2020-07-26 21:36:50 [main] - Successfully entered all jobs to execution
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-7] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X12345678, type=null]]
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-5] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X1234567, type=null]]
2020-07-26 21:36:55 [ForkJoinPool.commonPool-worker-3] - Proceeding to assign type for: ComplianceCandidate [device=[ipAddress=99.6.6.1, macAddress=0X123456, type=null]]

this is not the behavior i was hoping for, while the main thread is indeed not blocked, instead of seeing only one of these guys ForkJoinPool.commonPool-worker-7 printing every 5 seconds, I'm seeing 3 of them all printing at the same time

huangapple
  • 本文由 发表于 2020年7月27日 10:59:20
  • 转载请务必保留本文链接:https://java.coder-hub.com/63108093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定