Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThreadPoolExecutorFactoryBean add ability to prestart threads #1246

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport

private int keepAliveSeconds = 60;

private boolean allowCoreThreadTimeOut = false;

private int queueCapacity = Integer.MAX_VALUE;

private boolean allowCoreThreadTimeOut = false;

private boolean exposeUnconfigurableExecutor = false;

private boolean prestartAllCoreThreads = false;

private ExecutorService exposedExecutor;


Expand Down Expand Up @@ -118,6 +120,17 @@ public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}

/**
* Specify whether this FactoryBean should prestart all threads
* for the created executor.
* <p>Default is "false".
* Switch this flag to "true" to prestart the threads allocated for the current executor
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
*/
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
this.prestartAllCoreThreads = prestartAllCoreThreads;
}

/**
* Specify whether this FactoryBean should expose an unconfigurable
* decorator for the created executor.
Expand All @@ -142,6 +155,10 @@ protected ExecutorService initializeExecutor(
executor.allowCoreThreadTimeOut(true);
}

if (this.prestartAllCoreThreads) {
executor.prestartAllCoreThreads();
}

// Wrap executor with an unconfigurable decorator.
this.exposedExecutor = (this.exposeUnconfigurableExecutor ?
Executors.unconfigurableExecutorService(executor) : executor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,24 @@

package org.springframework.scheduling.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.FutureTask;

import org.junit.Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static org.junit.Assert.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

/**
* @author Juergen Hoeller
Expand All @@ -49,6 +55,21 @@ public String call() throws Exception {
assertEquals("foo", task.get());
}

@Test
public void executorWithPreStartedThreads() throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfigWithPreStartedThreads.class);
ThreadPoolExecutor executor = context.getBean("childExecutor", ThreadPoolExecutor.class);

verify(executor).prestartAllCoreThreads();
}

@Test
public void executorWithNoPreStartedThreads() throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfigWithNoPreStartedThreads.class);
ThreadPoolExecutor executor = context.getBean("childExecutor", ThreadPoolExecutor.class);

verify(executor, never()).prestartAllCoreThreads();
}

@Configuration
public static class ExecutorConfig {
Expand All @@ -62,6 +83,47 @@ public ThreadPoolExecutorFactoryBean executorFactory() {
public ExecutorService executor() {
return executorFactory().getObject();
}

}

@Configuration
public static class ExecutorConfigWithPreStartedThreads {

@Bean
public ThreadPoolExecutorFactoryBean executorChildFactory() {
ThreadPoolExecutorFactoryBeanMockingChild threadPoolExecutorFactoryBeanMockingChild = new ThreadPoolExecutorFactoryBeanMockingChild();
threadPoolExecutorFactoryBeanMockingChild.setPrestartAllCoreThreads(true);
return threadPoolExecutorFactoryBeanMockingChild;
}

@Bean
public ExecutorService childExecutor() {
return executorChildFactory().getObject();
}
}

@Configuration
public static class ExecutorConfigWithNoPreStartedThreads {

@Bean
public ThreadPoolExecutorFactoryBean executorChildFactory() {
return new ThreadPoolExecutorFactoryBeanMockingChild();
}

@Bean
public ExecutorService childExecutor() {
return executorChildFactory().getObject();
}
}

private static class ThreadPoolExecutorFactoryBeanMockingChild extends ThreadPoolExecutorFactoryBean {
@Override
protected ThreadPoolExecutor createExecutor(
int corePoolSize, int maxPoolSize, int keepAliveSeconds, BlockingQueue<Runnable> queue,
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {

return mock(ThreadPoolExecutor.class);
}
}

}