异步线程池的使用

合理使用异步线程开发项目能提高一个项目的并发量,减少响应时间。下面就简单介绍一下异步线程池的使用,参考博客:https://blog.csdn.net/hry2015/article/details/67640534

spring 对@Async定义异步任务的方法有3种:

1.最简单的异步调用,返回值为void;

2.带参数的异步调用,异步方法可以传入参数;

3.异常调用返回Future

代码如下:

package com.hry.spring.async.annotation;

import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

/**
 * 异步方法调用
 *
 * @author hry
 *
 */
@Component
public class AsyncDemo {
	private static final Logger log = LoggerFactory.getLogger(AsyncDemo.class);

	/**
	 * 最简单的异步调用,返回值为void
	 */
	@Async
	public void asyncInvokeSimplest() {
		log.info("asyncSimplest");
	}

	/**
	 * 带参数的异步调用 异步方法可以传入参数
	 *
	 * @param s
	 */
	@Async
	public void asyncInvokeWithParameter(String s) {
		log.info("asyncInvokeWithParameter, parementer={}", s);
	}

	/**
	 * 异常调用返回Future
	 *
	 * @param i
	 * @return
	 */
	@Async
	public Future<String> asyncInvokeReturnFuture(int i) {
		log.info("asyncInvokeReturnFuture, parementer={}", i);
		Future<String> future;
		try {
			Thread.sleep(1000 * 1);
			future = new AsyncResult<String>("success:" + i);
		} catch (InterruptedException e) {
			future = new AsyncResult<String>("error");
		}
		return future;
	}

}

  

spring启动配置的方式有两种:

1.注解;

2.XML配置文件

我们先说注解的方式:

@EnableAsync注解可以开启异步调用功能, public AsyncTaskExecutor taskExecutor() 方法自定义自己的线程池,线程池前缀”Anno-Executor”。如果不定义,则使用系统默认的线程池。代码如下:

package com.hry.spring.async.annotation;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * 通过@EnableAsync启动异步方法
 * @author hry
 *
 */
@SpringBootApplication
@EnableAsync // 启动异步调用
public class AsyncApplicationWithAnnotation {
	private static final Logger log = LoggerFactory.getLogger(AsyncApplicationWithAnnotation.class);

	/**
	 * 自定义异步线程池
	 * 	如果没有这个方法,则使用默认的线程池
	 * @return
	 */
    @Bean
    public AsyncTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("Anno-Executor");//设置线程名称的前缀
        executor.setCorePoolSize(5);//设置核心线程数
        executor.setMaxPoolSize(10);//设置最大线程数

        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
			@Override
			public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
				// .....
			}
		});
        // 使用预定义的异常处理类
        // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        return executor;
    }

	public static void main(String[] args) {
		log.info("Start AsyncApplication.. ");
		SpringApplication.run(AsyncApplicationWithAnnotation.class, args);
	}
}

 现在写测试类:

package com.hry.spring.async.annotation;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.hry.spring.async.annotation.AsyncApplicationWithAnnotation;
import com.hry.spring.async.annotation.AsyncDemo;

@RunWith(SpringRunner.class)
@SpringBootTest(classes=AsyncApplicationWithAnnotation.class)
public class AsyncApplicationWithAnnotationTests {
	@Autowired
	private AsyncDemo asyncDemo;

	@Test
	public void contextLoads() throws InterruptedException, ExecutionException {
		asyncDemo.asyncInvokeSimplest();
		asyncDemo.asyncInvokeWithParameter("test");
		Future<String> future = asyncDemo.asyncInvokeReturnFuture(1000);
		System.out.println(future.get());
	}
}

 启动测试类,结果如下:

说明启动异步线程池成功,执行上面的3个方法分别用了3个线程。

再说一下XML配置文件配置的方式:

我们先创建XML配置文件:

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
    default-lazy-init="false">  

  	<!-- 等价于 @EnableAsync, executor指定线程池 -->
  	<task:annotation-driven executor="xmlExecutor"/>
  	<!-- id指定线程池产生线程名称的前缀 -->
    <task:executor
        id="xmlExecutor"
        pool-size="3-20"
        queue-capacity="100"
	    keep-alive="120"
        rejection-policy="CALLER_RUNS"/>

</beans>

  

其中id表示线程名称的前缀,pool-size表示线程池的大小,“3-20”表示线程池的最大线程数为20,最小线程数为3,也可以设置成一个值,如:pool-size=5,则表示线程池的核心线程数和最大线程数相同,都是5。queue-capacity表示排队队列的长度。

项目启动时读取xml配置文件,如下:

package com.hry.spring.async.xml;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

/**
 * 通过XML启动异步
 * @author hry
 *
 */
@SpringBootApplication
@ImportResource("classpath:/async/spring_async.xml")
public class AsyncApplicationWithXML {
	private static final Logger log = LoggerFactory.getLogger(AsyncApplicationWithXML.class);

	public static void main(String[] args) {
		log.info("Start AsyncApplication.. ");
		SpringApplication.run(AsyncApplicationWithXML.class, args);
	}
}  

编写测试类:

package com.hry.spring.async.xml;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes=AsyncApplicationWithXML.class)
public class AsyncApplicationWithXMLTest {
	@Autowired
	private AsyncDemo asyncDemo;

	@Test
	public void contextLoads() throws InterruptedException, ExecutionException {
		asyncDemo.asyncInvokeSimplest();
		asyncDemo.asyncInvokeWithParameter("test");
		Future<String> future = asyncDemo.asyncInvokeReturnFuture(100);
		System.out.println(future.get());
	}
}

  

测试结果如下:

测试成功。

 

 

原文地址:https://www.cnblogs.com/gaopengfirst/p/10846179.html

时间: 2024-10-31 07:01:22

异步线程池的使用的相关文章

使用C++11 开发一个半同步半异步线程池

摘自:<深入应用C++11>第九章 实际中,主要有两种方法处理大量的并发任务,一种是一个请求由系统产生一个相应的处理请求的线程(一对一) 另外一种是系统预先生成一些用于处理请求的进程,当请求的任务来临时,先放入同步队列中,分配一个处理请求的进程去处理任务, 线程处理完任务后还可以重用,不会销毁,而是等待下次任务的到来.(一对多的线程池技术) 线程池技术,能避免大量线程的创建和销毁动作,节省资源,对于多核处理器,由于线程被分派配到多个cpu,会提高并行处理的效率. 线程池技术分为半同步半异步线程

c++11 实现半同步半异步线程池

感受: 随着深入学习,现代c++给我带来越来越多的惊喜- c++真的变强大了. 半同步半异步线程池: 其实很好理解,分为三层 同步层:通过IO复用或者其他多线程多进程等不断的将待处理事件添加到队列中,这个过程是同步进行的. 队列层:所有待处理事件都会放到这里.上一层事件放到这里,下一层从这里获取事件 异步层:事先创建好线程,让瞎猜呢和嗯不断的去处理队列层的任务,上层不关心这些,它只负责把任务放到队列里,所以对上层来说这里是异步的. 看张图: 如果你不熟悉c++11的内容 以下文章仅供参考 c++

异步线程池的实现(一)-------具体实现方法

本篇是这个内容的第一篇,主要是写:遇到的问题,和自己摸索实现的方法.后面还会有一篇是总结性地写线程池的相关内容(偏理论的). 一.背景介绍 朋友的项目开发到一定程度之后,又遇到了一些问题:在某些流程中的一些节点,由于是串联执行的.上一步要等下一步执行完毕:或者提交数据之后要等待后台其他系统处理完成之后,才能返回结果.这样就会导致,请求发起方不得不一直等待结果,用户体验很不好:从项目优化来说,模块与模块之间构成了强耦合,这也是不利于以后扩展的,更不用说访问量上来之后,肯定会抓瞎的问题.所以,我就着

(原创)C++半同步半异步线程池2

(原创)C++半同步半异步线程池 c++11 boost技术交流群:296561497,欢迎大家来交流技术. 线程池可以高效的处理任务,线程池中开启多个线程,等待同步队列中的任务到来,任务到来多个线程会抢着执行任务,当到来的任务太多,达到上限时需要等待片刻,任务上限保证内存不会溢出.线程池的效率和cpu核数相关,多核的话效率更高,线程数一般取cpu数量+2比较合适,否则线程过多,线程切换频繁反而会导致效率降低. 线程池有两个活动过程:1.外面不停的往线程池添加任务:2.线程池内部不停的取任务执行

半同步半异步线程池的实现(C++11)

简介 处理大量并发任务时,一个请求对应一个线程来处理任务,线程的创建和销毁将消耗过多的系统资源,并增加上下文切换代价.线程池技术通过在系统中预先创建一定数量的线程(通常和cpu核数相同),当任务到达时,从线程池中分配一个线程进行处理,线程在处理完任务之后不用销毁,等待重用. 线程池包括半同步半异步和领导者追随者两种实现方式.线程池包括三部分,第一层是同步服务层,它处理来自上层的任务请求.第二层是同步队列层,同步服务层中的任务将添加到队列中.第三层是异步服务层,多个线程同时处理队列中的任务. 先贴

异步线程池

1.创建类实现AsyncTaskExecutor, InitializingBean, DisposableBean接口,重写方法. import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.core.task

Springboot的异步线程池图鉴

1:定义线程池 @EnableAsync @Configuration class TaskPoolConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor

[email&#160;protected]异步线程池的配置及应用

示例: 1. 配置 @EnableAsync @Configuration public class TaskExecutorConfiguration { @Autowired private TaskExecutorProperties taskExecutorProperties; @Bean public Executor routeGen() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); execut

spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecutor; 可以发现,spring的  ThreadPoolTaskExecutor是使用的jdk中的java.util.concurrent.ThreadPoolExecutor进行实现, 直接看代码: @Override protected ExecutorService initializeExe