「java线程池异步返回值」java多线程返回值

博主:adminadmin 2022-11-23 12:35:16 63

今天给各位分享java线程池异步返回值的知识,其中也会对java多线程返回值进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

java 线程池异步任务需要处理异步结果会阻塞吗

1、关于异步:java中异步请求就是*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理

创建线程有哪两种方法,它们各自的优缺点是什么?

线程创建方式及优缺点

1.继承Thread类 2.实现Runnable接口3.实现Callable接口 4.线程池方式

优缺点

1.继承Thread类

优点 、代码简单 。缺点 、该类无法集成别的类。

2.实现Runnable接口

优点 、继承其他类。同一实现该接口的实例可以共享资源。缺点 、代码复杂

3.实现Callable

优点 、可以获得异步任务的返回值

4.线程池 、实现自动化装配,易于管理,循环利用资源。

满意还望采纳

Spring Boot中异步线程池@Async详解

1、消息队列MQ

2、线程池处理。

我们来看看Spring框架中如何去使用线程池来完成异步操作,以及分析背后的原理。

在Spring4中,Spring中引入了一个新的注解@Async,这个注解让我们在使用Spring完成异步操作变得非常方便。

Spring异步线程池的接口类,其实质是java.util.concurrent.Executor

Spring 已经实现的异常线程池:

Spring中用@Async注解标记的方法,称为异步方法。在spring boot应用中使用@Async很简单:

1、调用异步方法类上或者启动类加上注解@EnableAsync

2、在需要被异步调用的方法外加上@Async

3、所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象;

启动类加上注解@EnableAsync:

在需要被异步调用的方法外加上@Async,同时类AsyncService加上注解@Service或者@Component,使其对象成为Spring容器管理的bean对象;

这里需要注意的是:

1、同一个类里面调用异步方法不生效:原因默认类内的方法调用不会被aop拦截,即调用方和被调用方是在同一个类中,是无法产生切面的,该对象没有被Spring容器管理。即@Async方法不生效。

解决办法:如果要使同一个类中的方法之间调用也被拦截,需要使用spring容器中的实例对象,而不是使用默认的this,因为通过bean实例的调用才会被spring的aop拦截

本例使用方法:AsyncService asyncService = context.getBean(AsyncService.class); 然后使用这个引用调用本地的方法即可达到被拦截的目的

备注:这种方法只能拦截protected,default,public方法,private方法无法拦截。这个是spring aop的一个机制。

2、如果不自定义异步方法的线程池默认使用SimpleAsyncTaskExecutor。SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。并发大的时候会产生严重的性能问题。

3、异步方法返回类型只能有两种:void和java.util.concurrent.Future。

1)当返回类型为void的时候,方法调用过程产生的异常不会抛到调用者层面,

可以通过注AsyncUncaughtExceptionHandler来捕获此类异常

2)当返回类型为Future的时候,方法调用过程产生的异常会抛到调用者层面

在Spring Boot主类中定义一个线程池,public Executor taskExecutor() 方法用于自定义自己的线程池,线程池前缀”taskExecutor-”。如果不定义,则使用系统默认的线程池。

上面我们通过ThreadPoolTaskExecutor创建了一个线程池,同时设置了如下参数:

核心线程数10:线程池创建时初始化的线程数

最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程

缓冲队列200:用来缓冲执行任务的队列

允许线程的空闲时间60秒:超过了核心线程数之外的线程,在空闲时间到达之后会被销毁

线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池

线程池对拒绝任务的处理策略:此处采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已被关闭,则会丢弃该任务

设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean

设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住

也可以单独类来配置线程池:

只需要在@Async注解中指定线程池名即可

Bean文件配置: spring_async.xml

1. 线程的前缀为xmlExecutor

2. 启动异步线程池配置

启动类导入xml文件:

线 程池参数说明

1. ‘id’ : 线程名称的前缀

2. ‘pool-size’:线程池的大小。支持范围”min-max”和固定值(此时线程池core和max sizes相同)

3. ‘queue-capacity’ :排队队列长度

4. ‘rejection-policy’: 对方拒绝的任务处理策略

5. ‘keep-alive’ : 线程保护时间(单位秒)

上面也提到:在调用方法时,可能出现方法中抛出异常的情况。在异步中主要有有两种异常处理方法:

a) 、一种是在调用future的get时捕获异常;

b)、 在异常方法中直接捕获异常

实现AsyncConfigurer接口对异常线程池更加细粒度的控制

a) 创建线程自己的线程池

b) 对void方法抛出的异常处理的类AsyncUncaughtExceptionHandler

上面也提到:如果不自定义异步方法的线程池默认使用SimpleAsyncTaskExecutor。SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。并发大的时候会产生严重的性能问题。

一般的错误OOM:OutOfMemoryError:unable to create new native thread,创建线程数量太多,占用内存过大.

解决办法:一般最好使用自定义线程池,做一些特殊策略, 比如自定义拒绝策略,如果队列满了,则拒绝处理该任务。

原文链接:

java 如何创建一个有返回值的线程

可以通过实现Callable接口创建一个有返回值的线程,代码如下:

import java.util.concurrent.*;

public class MyThread implements CallableInteger {

    private int count;

    public MyThread(int count) {

        this.count = count;

    }

    @Override

    public Integer call() throws Exception {

        // 此处是线程要处理的业务代码,此处实现的是对count变量加1的操作

        count += 1;

        Thread.sleep(1000);

        return count;

    }

    public static void main(String[] args) {

        // 创建线程实例

        MyThread myThread = new MyThread(1);

        // 创建一个大小为10的线程池

        ExecutorService executor = Executors.newFixedThreadPool(10);

        // 将线程提交到线程池执行

        FutureInteger future = executor.submit(myThread);

        try {

            // 调用get方法获取线程执行结果,在线程执行完成前该方法会一直阻塞

            Integer result = future.get();

            System.out.println(result);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

//        try {

//            // 这种写法可以设置线程执行的超时时间,当线程超过指定的时间还未执行完成时会抛出TimeoutException异常

//            // 示例中表示线程超过1000毫秒还没执行完就会抛出超时异常

//            Integer result = future.get(1000, TimeUnit.MILLISECONDS);

//            System.out.println(result);

//        } catch (InterruptedException e) {

//            e.printStackTrace();

//        } catch (ExecutionException e) {

//            e.printStackTrace();

//        } catch (TimeoutException e) {

//            e.printStackTrace();

//        }

    }

}

关于java线程池异步返回值和java多线程返回值的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-11-23,除非注明,否则均为首码项目网原创文章,转载请注明出处。