基于spring框架实现多线程

为什么还要使用Spring来实现多线程呢?有两个原因,第一使用Spring比使用JDK原生的并发API更简单。第二我们的应用环境一般都会集成Spring,我们的Bean也都交给Spring来进行管理,那么使用Spring来实现多线程更加简单,更加优雅。

从Spring3同时也是新增了Java的配置方式,而且Java配置方式也逐渐成为主流的Spring的配置方式,因此后面的例子都是以Java的配置进行演示。

首先定义配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
/**
 * 方式一
 * 多线程配置类
 */
@Configuration
@ComponentScan("com.xuecheng.manage_cms.service1")
@EnableAsync  // 启用异步任务
public class ThreadConfig {
     

    // 这里是声明一个bean,类似于xml中的标签。
    // Executor 就是一个线程池
    @Bean
    public Executor getExecutor() {
     
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

定义要执行的任务

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.UUID;
/**
 * 多线程
 * 定义要执行的方法
 */
@Service // 注解的方式把AsyncService交给Spring来管理
public class AsynTaskService {
     

    // 这里可以注入spring中管理的其他bean,这也是使用spring来实现多线程的一大优势

    @Async    // 这里进行标注为异步任务,在执行此方法的时候,会单独开启线程来执行
    public void f1() {
     
        System.out.println("f1 : " + Thread.currentThread().getName() + "   " + UUID.randomUUID().toString());
        try {
     
            Thread.sleep(1000);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
    }

    @Async
    public void f2() {
     
        System.out.println("f2 : " + Thread.currentThread().getName() + "   " + UUID.randomUUID().toString());
        try {
     
            Thread.sleep(1000);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
    }
}

测试类

import com.xuecheng.manage_cms.service1.AsynTaskService;
import com.xuecheng.manage_cms.service1.ThreadConfig1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
/**
 * 测试多线程
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestThread {
     

    @Test
    public void TestThread() {
     

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ThreadConfig.class);
        AsynTaskService service = context.getBean(AsynTaskService.class);
        for (int i = 0; i < 10; i++) {
     
            service.f1(); // 执行异步任务
            service.f2();
        }
        context.close();
    }
}

运行结果:
在这里插入图片描述
关于线程池的配置还有一种方式,就是直接实现AsyncConfigurer接口,重写getAsyncExecutor方法即可,代码如下:

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
 * 方式二
 * 线程池的配置另一种方式,就是直接实现AsyncConfigurer接口,重写getAsyncExecutor方法即可
 */
@Configuration
@ComponentScan("com.xuecheng.manage_cms.service1")
@EnableAsync
public class ThreadConfig1 implements AsyncConfigurer {
     

    @Override
    public Executor getAsyncExecutor() {
     
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
     
        return null;
    }
}

欢迎留言讨论。

你可能感兴趣的:(多线程)