首页 > 其他分享 >Spring框架中的线程池

Spring框架中的线程池

时间:2023-06-16 09:44:25浏览次数:37  
标签:执行器 异步 框架 Spring 任务 线程 executor Async

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

Spring框架中的线程池

使用Java的ExecutorService接口实现

ExecutorService是Java提供的用于管理线程池的高级工具。

下面是在Spring框架中使用线程池的一般步骤:

导入所需的依赖

首先,确保你的项目中包含了使用线程池所需的依赖。通常情况下,你可以使用Spring Boot来创建项目,它会自动包含线程池相关的依赖。

创建线程池

在Spring中,你可以通过配置文件或使用Java代码来创建线程池。如果你使用配置文件,可以在application.propertiesapplication.yml文件中配置线程池的属性。如果你使用Java代码,可以通过创建ThreadPoolTaskExecutorThreadPoolExecutor对象来实现。

// 通过Java代码创建线程池
@Bean
public ExecutorService taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(10); // 设置核心线程数
    executor.setMaxPoolSize(20); // 设置最大线程数
    executor.setQueueCapacity(30); // 设置队列容量
    executor.setThreadNamePrefix("MyThread-"); // 设置线程名前缀
    executor.initialize();
    return executor;
}

在需要使用线程池的地方注入它

在你的代码中,如果你需要使用线程池来执行异步任务或并发处理,你可以通过在需要使用的地方注入线程池来实现。

@Autowired
private ExecutorService taskExecutor;

提交任务给线程池

一旦你注入了线程池,你就可以使用它来提交任务。

taskExecutor.execute(() -> {
    // 在这里编写你的任务逻辑
});

或者,如果你需要获取任务的结果,你可以使用submit()方法。

Future<Result> future = taskExecutor.submit(() -> {
    // 在这里编写你的任务逻辑,并返回一个结果
    return result;
});

销毁线程池

在Spring应用程序关闭时,确保销毁线程池以释放资源。

@PreDestroy
public void shutdown() {
    if (taskExecutor instanceof ExecutorService) {
        ((ExecutorService) taskExecutor).shutdown();
    }
}

以上是在Spring框架中使用线程池的基本步骤。你可以根据自己的需求和具体的场景来配置线程池的属性和使用方式。

使用@Async注解使用异步线程池执行任务

在Spring框架中,使用@Async注解可以将方法标记为异步执行的方法,使其在调用时会被自动提交到线程池中执行,而不会阻塞主线程。

以下是使用@Async注解的步骤:

导入所需的依赖

确保你的项目中包含了使用@Async注解所需的依赖。通常情况下,你可以使用Spring Boot来创建项目,它会自动包含相关的依赖。

启用异步支持

在Spring配置中,你需要启用异步支持。如果你使用Java配置方式,可以在配置类上加上@EnableAsync注解。如果你使用XML配置方式,可以在XML配置文件中添加<task:annotation-driven executor="taskExecutor" />

在需要异步执行的方法上添加@Async注解

@Async注解添加到你希望异步执行的方法上。

@Async
public void asyncMethod() {
    // 异步执行的方法逻辑
}

配置线程池并指定任务执行器名称(可选)

Spring框架默认使用SimpleAsyncTaskExecutor作为任务执行器,但你也可以自定义线程池并指定任务执行器的名称。在配置类中创建一个TaskExecutor的bean,并通过@Async注解的value属性或Executor参数指定任务执行器的名称。

@Bean("taskExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(30);
    executor.setThreadNamePrefix("MyThread-");
    executor.initialize();
    return executor;
}

// 使用@Async注解并指定任务执行器名称
@Async("taskExecutor")
public void asyncMethodWithCustomExecutor() {
    // 异步执行的方法逻辑
}

关于SimpleAsyncTaskExecutor

SimpleAsyncTaskExecutor是Spring框架提供的默认的任务执行器,它是基于Java的Executor接口实现的简单的线程池。

要配置SimpleAsyncTaskExecutor,你可以在Spring的配置类中创建一个TaskExecutor的bean,并将其返回。以下是一个示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;

@Configuration
public class AppConfig {

    @Bean
    public TaskExecutor taskExecutor() {
        SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
        executor.setConcurrencyLimit(10); // 设置并发限制,默认为无限制
        executor.setThreadNamePrefix("MyThread-"); // 设置线程名前缀
        return executor;
    }

}

在上述示例中,我们创建了一个TaskExecutor的bean,并将其返回。SimpleAsyncTaskExecutor的实例被创建,并通过setConcurrencyLimit()方法设置了并发限制,这是可选的,默认为无限制。setThreadNamePrefix()方法设置了线程名的前缀,以便于识别任务执行的线程。

你可以根据需要进行其他配置,SimpleAsyncTaskExecutor还提供了其他方法,例如setThreadGroupName()setDaemon()等,可以根据具体需求进行设置。

在使用SimpleAsyncTaskExecutor时,它会根据需要创建新的线程来执行任务,不会重用线程。因此,它适用于短期、简单的异步任务,但对于长期运行的任务或需要复杂线程池配置的场景,可能需要使用其他实现,如ThreadPoolTaskExecutor

请注意,SimpleAsyncTaskExecutor不适合高负载的应用程序,因为它没有线程池的管理机制,并且没有对队列容量、拒绝策略等进行配置。如果你的应用程序需要更高级的线程池管理功能,建议使用ThreadPoolTaskExecutor或其他支持更多配置选项的任务执行器。

关于ThreadPoolTaskExecutor

ThreadPoolTaskExecutor是Spring框架提供的一个基于Java的ThreadPoolExecutor的封装,它提供了更多的线程池管理功能和配置选项。

要配置ThreadPoolTaskExecutor,你可以在Spring的配置类中创建一个TaskExecutor的bean,并进行相应的配置。以下是一个示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.core.task.TaskExecutor;

@Configuration
public class AppConfig {

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10); // 设置核心线程数
        executor.setMaxPoolSize(20); // 设置最大线程数
        executor.setQueueCapacity(30); // 设置队列容量
        executor.setThreadNamePrefix("MyThread-"); // 设置线程名前缀
        executor.initialize();
        return executor;
    }

}

在上述示例中,我们创建了一个TaskExecutor的bean,并将其返回。ThreadPoolTaskExecutor的实例被创建,并通过一系列的set方法进行配置,包括:

  • setCorePoolSize(int corePoolSize): 设置核心线程数,即线程池中保持的线程数量。
  • setMaxPoolSize(int maxPoolSize): 设置最大线程数,即线程池允许的最大线程数量。
  • setQueueCapacity(int queueCapacity): 设置队列容量,即线程池任务队列的最大容量。
  • setThreadNamePrefix(String threadNamePrefix): 设置线程名的前缀,以便于识别任务执行的线程。
  • initialize(): 初始化线程池。

除了上述方法,ThreadPoolTaskExecutor还提供了其他配置选项,如setKeepAliveSeconds()setAllowCoreThreadTimeOut()setRejectedExecutionHandler()等,可以根据具体需求进行设置。

配置完成后,你可以将ThreadPoolTaskExecutor用作任务执行器,通过在@Async注解中指定任务执行器的名称或通过注入使用它。

请注意,ThreadPoolTaskExecutor提供了线程池的管理功能,可以根据任务的情况自动调整线程池的大小,对于长期运行的异步任务或需要更高级的线程池管理的场景,它是更常用的选择。

调用异步方法

在其他组件或类中,直接调用带有@Async注解的异步方法即可。

myService.asyncMethod();

@Async注解可以在后面加入一个名字,用于指定具体的任务执行器,如上面的示例中的@Async("taskExecutor")。这样做的好处是,你可以针对不同的异步任务使用不同的线程池或任务执行器。

注意事项:

  • 异步方法必须定义在Spring管理的Bean中,因为Spring会通过代理来拦截方法调用并将其提交给线程池。
  • 使用@Async注解时,如果异步方法内部发生了异常,调用者不会收到异常,因为异步方法在独立的线程中执行。若需要捕获异常,可以使用Future来获取异步任务的执行结果并处理异常。
  • 确保在Spring的配置中启用了异步支持,否则@Async注解将不起作用。

这些是使用@Async注解实现异步方法的基本步骤,可以根据具体需求进行配置和使用。

@Async的实现原理

@Async注解的实现原理使用了AOP、动态代理、Java反射、线程池、Runnable和Callable接口、Future接口、Java并发类库等技术和类库,通过这些技术和类库的组合,实现了异步方法的调用和执行。

异步方法的代理生成

当Spring扫描到带有@Async注解的方法时,它会生成一个代理对象来封装该方法。

以下是Spring框架中生成代理对象的代码示例:

public class AsyncAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered {

    // ...

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class<?> targetClass = AopUtils.getTargetClass(bean);
        for (Method method : targetClass.getMethods()) {
            Async asyncAnnotation = AnnotationUtils.findAnnotation(method, Async.class);
            if (asyncAnnotation != null) {
                // 创建代理对象
                Object proxy = createAsyncProxy(bean, beanName, method);
                return proxy;
            }
        }
        return bean;
    }

    private Object createAsyncProxy(Object bean, String beanName, Method method) {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(bean);
        proxyFactory.addAdvisor(asyncAdvisor);
        proxyFactory.setFrozen(true);
        proxyFactory.setProxyTargetClass(true);
        return proxyFactory.getProxy();
    }

    // ...

}

在上述代码中,AsyncAnnotationBeanPostProcessor实现了BeanPostProcessor接口,用于在Bean初始化之前对带有@Async注解的方法进行处理。当Spring扫描到带有@Async注解的方法时,postProcessBeforeInitialization()方法会被调用。

postProcessBeforeInitialization()方法中,首先通过AopUtils.getTargetClass(bean)获取目标类的类型,然后遍历目标类的所有方法。对于每个方法,使用AnnotationUtils.findAnnotation(method, Async.class)查找是否有@Async注解。

如果找到了带有@Async注解的方法,就会调用createAsyncProxy()方法创建代理对象。在createAsyncProxy()方法中,通过ProxyFactory创建一个代理工厂,并设置目标对象、添加asyncAdvisor(异步处理的通知器),以及其他配置。最后调用proxyFactory.getProxy()获取代理对象,并将其返回。

通过以上代码,Spring框架在扫描到带有@Async注解的方法时,会生成一个代理对象来封装该方法,实现异步调用的功能。这样,在调用带有@Async注解的方法时,实际上是通过代理对象来调用的,从而实现了异步执行。

任务执行器的选择

根据@Async注解的配置,Spring会根据指定的任务执行器名称选择相应的任务执行器。如果没有指定名称,它将使用默认的任务执行器。

在Spring中,根据@Async注解的配置选择任务执行器的过程涉及以下几个关键的源码部分:

AsyncAnnotationBeanPostProcessor

该类是一个BeanPostProcessor,用于处理带有@Async注解的方法。在方法postProcessBeforeInitialization()中,它会检查方法上的@Async注解的配置,并根据配置选择任务执行器。

AsyncConfigurer接口

该接口定义了配置任务执行器的方法。你可以通过实现该接口来自定义任务执行器的配置。其中,getAsyncExecutor()方法用于返回一个Executor对象,即任务执行器。

AnnotationAsyncExecutionInterceptor

该类是一个AOP的MethodInterceptor,用于在调用带有@Async注解的方法时进行拦截。在invoke()方法中,它会检查方法上的@Async注解的配置,并从AsyncAnnotationInterceptor中获取任务执行器。

AsyncAnnotationInterceptor

该类是一个AOP的MethodInterceptor,用于处理带有@Async注解的方法。在invoke()方法中,它会获取任务执行器,并使用任务执行器来执行异步任务。

相关的源码示例

public class AsyncAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered {

    private AsyncConfigurer asyncConfigurer;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // ...

        // 根据@Async注解的配置获取任务执行器
        Executor executor = getExecutor(asyncAnnotation);

        // ...

        // 创建代理对象并设置任务执行器
        Object proxy = createAsyncProxy(bean, beanName, method, executor);

        // ...
    }

    private Executor getExecutor(Async asyncAnnotation) {
        // 从AsyncConfigurer中获取任务执行器
        Executor executor = this.asyncConfigurer.getAsyncExecutor();
        if (executor == null && this.asyncConfigurer instanceof ApplicationContextAware) {
            executor = ((ApplicationContextAware) this.asyncConfigurer).getApplicationContext()
                    .getBean(TaskExecutor.class);
        }
        if (executor == null) {
            throw new IllegalStateException("No executor specified for async annotation processing");
        }
        return executor;
    }

    // ...

    private Object createAsyncProxy(Object bean, String beanName, Method method, Executor executor) {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(bean);
        proxyFactory.addAdvisor(asyncAdvisor);

        // 设置任务执行器
        proxyFactory.addAdvice(new AnnotationAsyncExecutionInterceptor(executor));

        proxyFactory.setFrozen(true);
        proxyFactory.setProxyTargetClass(true);
        return proxyFactory.getProxy();
    }

    // ...
}

public class AnnotationAsyncExecutionInterceptor implements MethodInterceptor {

    private final Executor executor;

    public AnnotationAsyncExecutionInterceptor(Executor executor) {
        this.executor = executor;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 获取目标方法上的@Async注解的配置信息

        // ...

        // 执行异步任务
        Future<?> future = executor.submit(task);

        // ...
    }

    // ...
}

在上述代码中,AsyncAnnotationBeanPostProcessor类通过getExecutor()方法获取任务执行器,该方法会优先从AsyncConfigurer中获取执行

器,如果未配置,则从Spring容器中获取TaskExecutor bean。然后,在创建代理对象时,将任务执行器传递给AnnotationAsyncExecutionInterceptor

AnnotationAsyncExecutionInterceptor类的invoke()方法中,使用获取到的任务执行器来执行异步任务,通过executor.submit(task)将任务提交给执行器。

通过上述源码,当Spring扫描到带有@Async注解的方法时,会根据配置获取任务执行器,并将其传递给代理对象,在执行异步方法时使用相应的任务执行器。这样就可以根据配置选择不同的任务执行器来处理异步方法的调用。

方法调用的封装

代理对象在调用异步方法时,会将该方法的执行请求封装成一个Runnable或Callable的任务,并提交给任务执行器。任务执行器会负责管理线程池,并在合适的时间执行异步任务。

在Spring中,代理对象在调用异步方法时,会将该方法的执行请求封装成一个RunnableCallable的任务,并提交给任务执行器。这个过程涉及以下关键的源码部分:

AnnotationAsyncExecutionInterceptor

该类是一个AOP的MethodInterceptor,用于处理带有@Async注解的方法。在invoke()方法中,它会将异步方法的执行请求封装成RunnableCallable的任务对象。

AsyncExecutionInterceptor.AsyncExecutionRunnable类和AsyncExecutionInterceptor.AsyncExecutionCallable

这两个类分别实现了RunnableCallable接口,用于封装异步方法的执行逻辑。

TaskExecutor接口和其实现类

Spring提供了多个实现了TaskExecutor接口的任务执行器,例如ThreadPoolTaskExecutorSimpleAsyncTaskExecutor等。任务执行器负责管理线程池,并执行提交的任务。

相关源码示例

public class AnnotationAsyncExecutionInterceptor implements MethodInterceptor {

    private final Executor executor;

    public AnnotationAsyncExecutionInterceptor(Executor executor) {
        this.executor = executor;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 获取目标方法上的@Async注解的配置信息

        // ...

        // 封装异步任务
        Runnable task = new AsyncExecutionRunnable(executor, asyncAnnotation, invocation);

        // 提交异步任务给任务执行器
        executor.execute(task);

        // 如果有返回值,则返回Future对象
        if (hasReturnType) {
            // 创建并返回Future对象
            return createFutureResult(asyncAnnotation, task);
        } else {
            return null;
        }
    }

    // ...
}

public class AsyncExecutionRunnable implements Runnable {

    private final Executor executor;
    private final Async asyncAnnotation;
    private final MethodInvocation invocation;

    public AsyncExecutionRunnable(Executor executor, Async asyncAnnotation, MethodInvocation invocation) {
        this.executor = executor;
        this.asyncAnnotation = asyncAnnotation;
        this.invocation = invocation;
    }

    @Override
    public void run() {
        try {
            // 执行异步方法
            invocation.proceed();
        } catch (Throwable ex) {
            // 处理异常
        }
    }
}

public interface TaskExecutor {

    void execute(Runnable task);

    // ...
}

public class ThreadPoolTaskExecutor implements TaskExecutor {

    // ...

    @Override
    public void execute(Runnable task) {
        // 提交任务给线程池执行
        getThreadPoolExecutor().execute(task);
    }

    // ...
}

在上述代码中,AnnotationAsyncExecutionInterceptor类的invoke()方法中,首先根据@Async注解的配置信息,创建一个AsyncExecutionRunnable对象,将任务执行逻辑封装在其中。

接着,通过调用任务执行器的execute()方法,将AsyncExecutionRunnable对象提交给任务执行器执行。任务执行器在内部会从线程池中获取一个空闲的线程,并执行run()方法中的异步方法调用。

当异步方法执行完成或出现异常时,任务执行器会进行相应的处理。

通过以上源码,可以看出代理对象在调用异步方法时,会将异步方法的执行请求封装成一个RunnableCallable的任务,并提交给任务执行器来执行。这样就实现了异步方法的调用和执行。

异步任务的执行

任务执行器会从线程池中获取一个空闲的线程来执行异步任务。异步任务的执行可能会被放入线程池的任务队列中,直到有线程可用为止。

异步方法的返回值处理

如果异步方法有返回值,代理对象会返回一个Future对象,用于获取异步方法执行的结果。你可以通过Future对象来获取异步方法的返回值或处理异常。

更多异步线程池的库或框架

除了使用@Async注解和自定义线程池外,在Spring框架中,还可以结合其他异步线程池的库或框架来实现异步任务的执行。以下是一些常见的异步线程池的库或框架:

Guava

Guava是Google提供的Java工具库,其中包含了一个ListeningExecutorService接口,可以将ExecutorService转换为支持异步操作的执行器。

CompletableFuture

CompletableFuture是Java 8引入的一个类,提供了一种方便的方式来执行异步任务。可以结合CompletableFutureExecutor来实现异步任务的执行。

用法

CompletableFuture是Java 8中引入的一个类,用于支持异步编程和处理异步任务的结果。它提供了一种方便的方式来处理异步操作,并支持将多个异步任务组合在一起。下面是CompletableFuture的一些常用用法以及如何与Spring Boot一起使用:

  1. 创建一个异步任务:

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        // 异步任务的逻辑
        return "Hello, World!";
    });
    
  2. 调用异步任务的结果:

    future.thenAccept(result -> {
        // 处理异步任务的结果
        System.out.println(result);
    });
    
  3. 组合多个异步任务:

    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
    CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
    
    CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);
    
    combinedFuture.thenAccept(result -> {
        // 处理组合异步任务的结果
        System.out.println(result);
    });
    
  4. 异步任务的异常处理:

    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
        // 异步任务的逻辑
        throw new RuntimeException("Something went wrong");
    });
    
    future.exceptionally(ex -> {
        // 处理异步任务的异常
        System.err.println("Exception: " + ex.getMessage());
        return 0; // 设置默认值
    });
    

与springboot集成

与Spring Boot一起使用CompletableFuture时,你可以将异步任务作为Spring Bean的方法,并使用@Async注解进行标记,以便在Spring容器中进行管理和调用。以下是一个示例:

  1. 在Spring Boot应用程序的配置类中,启用异步支持:

    @Configuration
    @EnableAsync
    public class AppConfig {
        // 配置其他Bean和设置
    
        // 声明异步任务执行器
        @Bean
        public Executor asyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            // 配置线程池参数
            // ...
            return executor;
        }
    }
    
  2. 在Spring Bean中定义一个异步方法,使用CompletableFuture进行异步操作:

    @Service
    public class MyService {
        @Async
        public CompletableFuture<String> doAsyncTask() {
            CompletableFuture<String> future = new CompletableFuture<>();
            // 异步任务的逻辑
            // ...
            return future;
        }
    }
    
  3. 在其他组件中调用异步方法,并处理异步结果:

    @RestController
    public class MyController {
        @Autowired
        private MyService myService;
    
        @GetMapping("/async")
        public ResponseEntity<CompletableFuture<String>> asyncEndpoint() {
            CompletableFuture<String> future = myService.doAsyncTask();
            return ResponseEntity.ok(future);
        }
    }
    

通过将异步任务定义为Spring Bean中的方法,并使用@Async注解进行标记,Spring Boot将自动为这些方法创建异步代理,使它们能够在单独的线程中执行。然后,你可以在其他组件中调用这些异步方法,并使用CompletableFuture来处理异步任务的结果。

在异步操作时,相比于Executors.newSingleThreadExecutor().submit,使用CompletableFuture.supplyAsync的优势

相比于Executors.newSingleThreadExecutor().submit,使用CompletableFuture.supplyAsync有以下几个好处:

  1. 异步任务的创建和执行更加简洁:使用CompletableFuture.supplyAsync可以直接将异步任务的逻辑封装在Lambda表达式中,并将其作为参数传递给方法。这样可以更加简洁地创建和执行异步任务,而不需要显式地创建ExecutorCallable对象。

  2. 支持更多的组合和链式操作:CompletableFuture提供了丰富的方法来处理异步任务的结果。你可以使用thenApplythenAcceptthenCombine等方法来对异步任务的结果进行转换、处理和组合。这使得在异步任务之间进行链式操作和数据流转变变得更加便捷。

  3. 支持异常处理和超时控制:CompletableFuture提供了方法来处理异步任务的异常情况,如exceptionallyhandle等。它还支持设置异步任务的超时时间,通过get方法的重载版本来控制等待异步结果的超时时间。这样可以更好地管理和处理异步任务中可能出现的异常和超时情况。

  4. 更灵活的执行器选择:CompletableFuture允许你传入自定义的执行器(Executor)来执行异步任务。这样你可以根据需求选择不同类型的执行器,如固定大小线程池、缓存线程池等,以满足特定的并发需求。

  5. 支持函数式编程:CompletableFuture采用了函数式编程的风格,通过方法链式调用和Lambda表达式来组织异步任务的逻辑。这种风格更加符合现代Java开发的趋势,并提供了更高的可读性和可维护性。

综上所述,使用CompletableFuture.supplyAsync相比于Executors.newSingleThreadExecutor().submit具有更多的优势,能够提供更灵活、更简洁、更可组合的异步任务编程方式。

Apache Commons

Apache Commons库提供了ExecutorService的实现,例如BasicThreadFactoryDefaultExecutorServiceFactory,可以用于创建和配置线程池。

BasicThreadFactory

它是一个简单的线程工厂,用于创建线程并配置其属性。你可以使用它来自定义线程的命名、优先级、守护状态等。

示例代码:

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(10,
        new BasicThreadFactory.Builder()
                .namingPattern("my-pool-thread-%d")
                .daemon(false)
                .priority(Thread.NORM_PRIORITY)
                .build());
// 执行任务
executor.execute(() -> {
    // 异步任务逻辑
});

DefaultExecutorServiceFactory

它是一个用于创建ExecutorService实例的工厂类。你可以使用它来创建具有自定义属性的ExecutorService,如核心线程数、最大线程数、线程存活时间等。

示例代码:

import org.apache.commons.lang3.concurrent.DefaultExecutorServiceFactory;

// 创建线程池工厂
DefaultExecutorServiceFactory factory = new DefaultExecutorServiceFactory();
factory.setMaximumPoolSize(10); // 设置最大线程数
factory.setThreadNamePrefix("my-pool-thread-"); // 设置线程名前缀

// 创建线程池
ExecutorService executor = factory.createExecutorService();

// 执行任务
executor.execute(() -> {
    // 异步任务逻辑
});

这些ExecutorService的实现类可以根据你的需求进行配置和使用,以满足不同的并发处理需求。可以根据自己的项目需要选择合适的实现类,并根据需要设置线程池的属性和配置。

Netflix Hystrix

Hystrix是Netflix开发的容错库,提供了异步执行和线程池隔离等功能。它可以与Spring集成,用于处理异步任务的执行和容错机制。

这些库或框架提供了更多的功能和选项,可以根据具体需求选择合适的异步线程池库或框架来实现异步任务的执行。在Spring中,可以通过配置或自定义TaskExecutor来集成这些库或框架,并使用它们来执行异步任务。

标签:执行器,异步,框架,Spring,任务,线程,executor,Async
From: https://www.cnblogs.com/chaojilaji/p/17484793.html

相关文章

  • Spring Boot 实现定时任务动态管理,太爽了!
    一、功能说明SpringBoot的定时任务的加强工具,实现对SpringBoot原生的定时任务进行动态管理,完全兼容原生@Scheduled注解,无需对原本的定时任务进行修改二、快速使用具体的功能已经封装成SpringBoot-starter即插即用:<dependency><groupId>com.github.guoyixing</groupId>......
  • springboot 中使用 redis 处理接口的幂等性
    什么是接口幂等性?数学中:在一次元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同;在二次元运算为幂等时,自己重复运算的结果等于它自己的元素。计算机学中:幂等指多次操作产生的影响只会跟一次执行的结果相同,通俗的说:某个行为重复的执行,最终获取的结果是相同的,不会因......
  • SpringBoot快速整合RabbitMq小案例
    对于一个直接创建的springBoot项目工程来说,可以按照以下步骤使用rabbitmq添加依赖:添加rabbitMQ的依赖。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>配置连接:在配置文件中配置虚拟主......
  • springboot项目启动
    报错:Couldnotresolveplaceholder'config.info'invalue"${config.info}"项目的bootstrap.yml配置文件的file-extension:yaml#这里我们获取的yaml格式的配置需要跟nacos配置列表的DataId结尾保持一致 ......
  • c++多线程 std::async std::future
    c++标准库中对线程操作有完善的封装,其中最常用到的如std::thread,std::async。EffectiveModernCpp中指出,应尽量使用std::async即基于任务的编程而非基于线程的编程。std::thread在前面的文章有提到过,此处仅对std::async作以记录。正如前面所说,std::async是基于任务的策略,本人理......
  • Java并发(十)----线程之守护线程
    默认情况下,Java进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。例:log.debug("开始运行...");Threadt1=newThread(()->{  log.debug("开始运行...");  sleep(2......
  • Java并发(十一)----线程五种状态与六种状态
    1、五种状态这是从操作系统层面来描述的【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),可以由CPU调度执行【运行状态】指获取了CPU时间片运行中的状态当CPU时间片用完,会从【......
  • SpringBoot集成kafka
    环境springboot2.7+kafka3.0。kafka安装请自行百度,话不多说直接上代码。1、添加maven依赖<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency> 2、application.yml添加kafka配置sp......
  • Java基础面试笔记(三) _Spring
    1.Spring框架有哪些主要模块?截止到目前Spring框架已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具、消息和测试模块。2.什么是依赖注入?什么是控制反转(IOC)?在Spring中,有几种依赖注入方式?依赖注入是在编译......
  • Spring Boot实现高质量的CRUD-4
    (续前文)8、Service实现类 ​​ Service实现类提供Service接口类的代码实现,Service实现类的命名为XXXManServiceImpl。​ Service实现类完成CRUD的核心处理代码,CRUD的不同方法,有各自常规的处理流程。8.1、新增单个对象​ 新增单个对象的方法名为addItem,处理流程如下: //新增......