使用 Spring 创建线程
Thread Creation with Spring
我是 Spring 的新手,正在尝试实现多线程程序。根据此 link、https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html 中的 Spring 文档,可以像
这样创建线程
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
但是 'Thread' 是使用 'new' 关键字创建的,并且 bean 不是由 Spring 管理的。因此它不能访问任何自动装配的组件。解决此问题的方法是在外部 class 自动装配组件并将其传递给其构造函数中的线程 class。
但是有没有其他正确的方法可以做到这一点,其中 Spring 可以负责初始化线程,以便线程可以访问所有自动连接的组件。
我正在创建的应用程序必须为它从队列接收到的每条新消息创建一个新线程。
我假设问题是关于初始化和使用 TaskExecutor 的方式?!因此,文档显示了执行此操作的方法:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
<bean id="taskExecutorExample" class="TaskExecutorExample">
<constructor-arg ref="taskExecutor" />
</bean>
或者您可以在您的代码中使用 @Bean
如
@Bean
public ThreadPoolTaskExecutor threadPool() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setQueueCapacity(25);
return pool;
}
@Bean
public TaskExecutorExample executorExample() {
return new TaskExecutorExample(threadPool());
}
然后就可以@Autowired
使用了。
关于corePoolSize
、maxPoolSize
、queueCapacity
的详情,可以参考这里:http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size
EDIT1: 收到Samo的说明后,我想更新为:
使用@Scope("prototype") 将@Component 添加到您的线程。然后使用 @Autowired 你的线程并执行 taskExecutor.execute(sampleThread)
此处示例:https://www.mkyong.com/spring/spring-and-java-thread-example/ 第 3 部分。Spring 线程池 + Spring 托管 bean 示例
希望对您有所帮助。
我是 Spring 的新手,正在尝试实现多线程程序。根据此 link、https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html 中的 Spring 文档,可以像
这样创建线程public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
但是 'Thread' 是使用 'new' 关键字创建的,并且 bean 不是由 Spring 管理的。因此它不能访问任何自动装配的组件。解决此问题的方法是在外部 class 自动装配组件并将其传递给其构造函数中的线程 class。
但是有没有其他正确的方法可以做到这一点,其中 Spring 可以负责初始化线程,以便线程可以访问所有自动连接的组件。
我正在创建的应用程序必须为它从队列接收到的每条新消息创建一个新线程。
我假设问题是关于初始化和使用 TaskExecutor 的方式?!因此,文档显示了执行此操作的方法:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
<bean id="taskExecutorExample" class="TaskExecutorExample">
<constructor-arg ref="taskExecutor" />
</bean>
或者您可以在您的代码中使用 @Bean
如
@Bean
public ThreadPoolTaskExecutor threadPool() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setQueueCapacity(25);
return pool;
}
@Bean
public TaskExecutorExample executorExample() {
return new TaskExecutorExample(threadPool());
}
然后就可以@Autowired
使用了。
关于corePoolSize
、maxPoolSize
、queueCapacity
的详情,可以参考这里:http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size
EDIT1: 收到Samo的说明后,我想更新为:
使用@Scope("prototype") 将@Component 添加到您的线程。然后使用 @Autowired 你的线程并执行 taskExecutor.execute(sampleThread)
此处示例:https://www.mkyong.com/spring/spring-and-java-thread-example/ 第 3 部分。Spring 线程池 + Spring 托管 bean 示例
希望对您有所帮助。