Skip to content

Commit 19a8b94

Browse files
committed
Polish "Expose prestartAllCoreThreads on ExecutorService"
See gh-1246
1 parent 2c53e9e commit 19a8b94

3 files changed

Lines changed: 52 additions & 61 deletions

File tree

‎spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolExecutorFactoryBean.java‎

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -73,14 +73,14 @@ public class ThreadPoolExecutorFactoryBean extends ExecutorConfigurationSupport
7373

7474
private int keepAliveSeconds = 60;
7575

76-
private int queueCapacity = Integer.MAX_VALUE;
77-
7876
private boolean allowCoreThreadTimeOut = false;
7977

80-
private boolean exposeUnconfigurableExecutor = false;
81-
8278
private boolean prestartAllCoreThreads = false;
8379

80+
private int queueCapacity = Integer.MAX_VALUE;
81+
82+
private boolean exposeUnconfigurableExecutor = false;
83+
8484
@Nullable
8585
private ExecutorService exposedExecutor;
8686

@@ -120,6 +120,16 @@ public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) {
120120
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
121121
}
122122

123+
/**
124+
* Specify whether to start all core threads, causing them to idly wait for work.
125+
* <p>Default is "false".
126+
* @since 5.3.14
127+
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
128+
*/
129+
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
130+
this.prestartAllCoreThreads = prestartAllCoreThreads;
131+
}
132+
123133
/**
124134
* Set the capacity for the ThreadPoolExecutor's BlockingQueue.
125135
* Default is {@code Integer.MAX_VALUE}.
@@ -132,17 +142,6 @@ public void setQueueCapacity(int queueCapacity) {
132142
this.queueCapacity = queueCapacity;
133143
}
134144

135-
/**
136-
* Specify whether this FactoryBean should prestart all threads
137-
* for the created executor.
138-
* <p>Default is "false".
139-
* Switch this flag to "true" to prestart the threads allocated for the current executor
140-
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
141-
*/
142-
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
143-
this.prestartAllCoreThreads = prestartAllCoreThreads;
144-
}
145-
146145
/**
147146
* Specify whether this FactoryBean should expose an unconfigurable
148147
* decorator for the created executor.
@@ -166,7 +165,6 @@ protected ExecutorService initializeExecutor(
166165
if (this.allowCoreThreadTimeOut) {
167166
executor.allowCoreThreadTimeOut(true);
168167
}
169-
170168
if (this.prestartAllCoreThreads) {
171169
executor.prestartAllCoreThreads();
172170
}

‎spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,6 +94,8 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
9494

9595
private boolean allowCoreThreadTimeOut = false;
9696

97+
private boolean prestartAllCoreThreads = false;
98+
9799
@Nullable
98100
private TaskDecorator taskDecorator;
99101

@@ -197,6 +199,16 @@ public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) {
197199
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
198200
}
199201

202+
/**
203+
* Specify whether to start all core threads, causing them to idly wait for work.
204+
* <p>Default is "false".
205+
* @since 5.3.14
206+
* @see java.util.concurrent.ThreadPoolExecutor#prestartAllCoreThreads
207+
*/
208+
public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads) {
209+
this.prestartAllCoreThreads = prestartAllCoreThreads;
210+
}
211+
200212
/**
201213
* Specify a custom {@link TaskDecorator} to be applied to any {@link Runnable}
202214
* about to be executed.
@@ -256,6 +268,9 @@ public void execute(Runnable command) {
256268
if (this.allowCoreThreadTimeOut) {
257269
executor.allowCoreThreadTimeOut(true);
258270
}
271+
if (this.prestartAllCoreThreads) {
272+
executor.prestartAllCoreThreads();
273+
}
259274

260275
this.threadPoolExecutor = executor;
261276
return executor;
Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,18 +25,20 @@
2525

2626
import org.junit.jupiter.api.Test;
2727

28-
import org.springframework.context.ApplicationContext;
2928
import org.springframework.context.ConfigurableApplicationContext;
3029
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3130
import org.springframework.context.annotation.Bean;
3231
import org.springframework.context.annotation.Configuration;
32+
import org.springframework.context.support.GenericApplicationContext;
3333

3434
import static org.assertj.core.api.Assertions.assertThat;
3535
import static org.mockito.Mockito.mock;
3636
import static org.mockito.Mockito.never;
3737
import static org.mockito.Mockito.verify;
3838

3939
/**
40+
* Tests for {@link ThreadPoolExecutorFactoryBean}.
41+
*
4042
* @author Juergen Hoeller
4143
*/
4244
class ThreadPoolExecutorFactoryBeanTests {
@@ -53,19 +55,25 @@ void defaultExecutor() throws Exception {
5355
}
5456

5557
@Test
56-
public void executorWithPreStartedThreads() throws Exception {
57-
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfigWithPreStartedThreads.class);
58-
ThreadPoolExecutor executor = context.getBean("childExecutor", ThreadPoolExecutor.class);
59-
60-
verify(executor).prestartAllCoreThreads();
58+
void executorWithDefaultSettingsDoesNotPrestartAllCoreThreads() {
59+
GenericApplicationContext context = new GenericApplicationContext();
60+
context.registerBean("taskExecutor", ThreadPoolExecutorFactoryBean.class, TestThreadPoolExecutorFactoryBean::new);
61+
context.refresh();
62+
ThreadPoolExecutor threadPoolExecutor = context.getBean(ThreadPoolExecutor.class);
63+
verify(threadPoolExecutor, never()).prestartAllCoreThreads();
6164
}
6265

6366
@Test
64-
public void executorWithNoPreStartedThreads() throws Exception {
65-
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfigWithNoPreStartedThreads.class);
66-
ThreadPoolExecutor executor = context.getBean("childExecutor", ThreadPoolExecutor.class);
67-
68-
verify(executor, never()).prestartAllCoreThreads();
67+
void executorWithPrestartAllCoreThreads() {
68+
GenericApplicationContext context = new GenericApplicationContext();
69+
context.registerBean("taskExecutor", ThreadPoolExecutorFactoryBean.class, () -> {
70+
TestThreadPoolExecutorFactoryBean factoryBean = new TestThreadPoolExecutorFactoryBean();
71+
factoryBean.setPrestartAllCoreThreads(true);
72+
return factoryBean;
73+
});
74+
context.refresh();
75+
ThreadPoolExecutor threadPoolExecutor = context.getBean(ThreadPoolExecutor.class);
76+
verify(threadPoolExecutor).prestartAllCoreThreads();
6977
}
7078

7179
@Configuration
@@ -78,37 +86,8 @@ ThreadPoolExecutorFactoryBean executor() {
7886

7987
}
8088

81-
@Configuration
82-
public static class ExecutorConfigWithPreStartedThreads {
83-
84-
@Bean
85-
public ThreadPoolExecutorFactoryBean executorChildFactory() {
86-
ThreadPoolExecutorFactoryBeanMockingChild threadPoolExecutorFactoryBeanMockingChild = new ThreadPoolExecutorFactoryBeanMockingChild();
87-
threadPoolExecutorFactoryBeanMockingChild.setPrestartAllCoreThreads(true);
88-
return threadPoolExecutorFactoryBeanMockingChild;
89-
}
90-
91-
@Bean
92-
public ExecutorService childExecutor() {
93-
return executorChildFactory().getObject();
94-
}
95-
}
89+
private static class TestThreadPoolExecutorFactoryBean extends ThreadPoolExecutorFactoryBean {
9690

97-
@Configuration
98-
public static class ExecutorConfigWithNoPreStartedThreads {
99-
100-
@Bean
101-
public ThreadPoolExecutorFactoryBean executorChildFactory() {
102-
return new ThreadPoolExecutorFactoryBeanMockingChild();
103-
}
104-
105-
@Bean
106-
public ExecutorService childExecutor() {
107-
return executorChildFactory().getObject();
108-
}
109-
}
110-
111-
private static class ThreadPoolExecutorFactoryBeanMockingChild extends ThreadPoolExecutorFactoryBean {
11291
@Override
11392
protected ThreadPoolExecutor createExecutor(
11493
int corePoolSize, int maxPoolSize, int keepAliveSeconds, BlockingQueue<Runnable> queue,
@@ -118,5 +97,4 @@ protected ThreadPoolExecutor createExecutor(
11897
}
11998
}
12099

121-
122100
}

0 commit comments

Comments
 (0)