Spring中线程池的用法

Posted Bwz_Learning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring中线程池的用法相关的知识,希望对你有一定的参考价值。

多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了。spring封装了java的多线程的实现,简化了开发。

简单的Hello程序

需要执行的线程类

一般是对于业务的封装.将具体的业务逻辑放到,线程内执行。

public class MessagePrinterTask implements Runnable 
    private String message;

    public MessagePrinterTask() 

    

    public MessagePrinterTask(String message) 
        this.message = message;
    

    public void run() 
        try 
            Thread.sleep(3000);
            System.out.println(message);
         catch (InterruptedException e) 
            e.printStackTrace();
        

    

    @Override
    public String toString() 
        return "MessagePrinterTask [message=" + message + "]";
    

spring 的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="  
http://www.springframework.org/schema/beans        
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
http://www.springframework.org/schema/context                
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 异步线程池 -->
    <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 核心线程数 -->
        <property name="corePoolSize" value="10" />
        <!-- 最大线程数 -->
        <property name="maxPoolSize" value="50" />
        <!-- 队列最大长度 >=mainExecutor.maxSize -->
        <property name="queueCapacity" value="100" />
        <!-- 线程池维护线程所允许的空闲时间 -->
        <property name="keepAliveSeconds" value="300" />
        <!-- 线程池对拒绝任务(无线程可用)的处理 策略 -->
        <!-- 若不作该处理,当线程满了,队列满了之后,继续往下增加任务,则抛出异常,拒绝该任务 -->
        <!-- <property name="rejectedExecutionHandler"> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> -->
    </bean>

    <!-- 处理业务的线程 -->
    <bean id="messagePrinterTask" class="com.test.sping.thread.MessagePrinterTask" />

</beans>

测试代码

  • 测试代码
import java.util.concurrent.Executor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ThreadTest 
    public static void main(String[] args) 

        ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Executor executor = (Executor) appContext.getBean("taskExecutor");

        for (int i = 0; i < 10; i++) 
            MessagePrinterTask mTask = new MessagePrinterTask("Message data  is " + i);
            executor.execute(mTask);
        

        System.out.println("I am from Main Thread ...");
    
  • 测试代码的运行结果
I am from Main Thread ...
Message data  is 5
Message data  is 7
Message data  is 6
Message data  is 8
Message data  is 4
Message data  is 9
Message data  is 0
Message data  is 3
Message data  is 1
Message data  is 2

在Spring容器启动的时候,启动一个线程

spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="  
http://www.springframework.org/schema/beans        
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
http://www.springframework.org/schema/context                
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 执行业务方法的线程 -->
    <bean id="scheduledThread" class="com.test.sping.thread.ScheduledThread" />

    <!-- 这样设置容器一启动就自动运行某个线程 start -->
    <bean id="springScheduleExecutorTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
        <!-- messagePrinterTask为线程类 -->
        <property name="runnable" ref="scheduledThread" />
        <!-- 容器加载5秒后开始执行 -->
        <property name="delay" value="5000" />
        <!-- 每次任务间隔 2秒,循环执行该线程,删除该设定就容器启动后只执行一次 -->
        <property name="period" value="2000" />
    </bean>

   <!-- 这样设置容器一启动就自动运行某个线程  -->
    <bean id="springScheduledExecutorFactoryBean" class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
        <property name="scheduledExecutorTasks">
            <list>
                <ref bean="springScheduleExecutorTask" />
            </list>
        </property>
    </bean>


</beans>

业务线程

public class ScheduledThread implements Runnable 

    @Override
    public void run() 

        while (true) 
            try 
                Thread.sleep(5000);
                System.out.println(" I am from ScheduledThread ...");
             catch (InterruptedException e) 
                e.printStackTrace();
            
        
    

测试代码

import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ScheduledThreadTest 
    public static void main(String[] args) 

        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-scheduled.xml");

        try 
            Thread.sleep(Integer.MAX_VALUE);
         catch (InterruptedException e) 
            e.printStackTrace();
        
    

以上是关于Spring中线程池的用法的主要内容,如果未能解决你的问题,请参考以下文章

线程池的用法及思考

Java 13都发布了,线程池的正确用法你知道吗?

转Spring线程及线程池的使用

浅聊JAVA 线程池的一般用法

JDK线程池和Spring线程池的使用

Spring+shiro session与线程池的坑