java异步的处理方式你知道吗

366 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

一、使用线程

1、new线程
new Thread(){
  @Override
  public void run() {
    longTimeMethod();
  }
}.start();
2、线程池

使用原生自带线程池或者自定义线程池

private ExecutorService executor = Executors.newCachedThreadPool() ;

public void fun() throws Exception {

    executor.submit(new Runnable(){

        @override

            public void run() {

                try {
                 //要执行的业务代码,我们这里没有写方法,可以让线程休息几秒进行测试

                    Thread.sleep(10000);

                    System.out.print("睡够啦~");

                }catch(Exception e) {

                    throw new RuntimeException("报错啦!!");

                }

            }

    });

}

二、Spring 的异步方法去执行@EnableAsync和@Async

第一步、在启动类或者配置类加上 @EnableAsync 注解。

第二步、在方法上或者在类上可以添加@Async注解用在类上,对类里面所有方法起作用

1、无返回值
@Service
public class AsynchronousService{
  @Async
  public void springAsynchronousMethod(){
    longTimeMethod();
  }
}

当其他类调用这个方法,异步就会生效。这里注意,一定要其他的类,如果在同类中调用,是不生效的。

2、Future接收返回值
@Service
public class AsynchronousService{
  @Async
  public Future springAsynchronousMethod(){
    Integer result = longTimeMethod();
    return new AsyncResult(result);
  }
}

如果调用之后接收返回值,不对返回值进行操作则为异步操作,进行操作则转为同步操作,等待对返回值操作完之后,才会继续执行主进程下面的流程

@Autowired
private AsynchronousService asynchronousService;

public void useAsynchronousMethod(){
    Future future = asynchronousService.springAsynchronousMethod();
    future.get(1000, TimeUnit.MILLISECONDS);
}

三、原生Future方法

private Future longTimeMethod2() {
  //创建线程池
  ExecutorService threadPool = Executors.newCachedThreadPool();
  //获取异步Future对象
  Future future = threadPool.submit(new Callable() {
    @Override
    public Integer call() throwsException {
        return longTimeMethod();
    }
  });
  return future;
}


//我们需要执行的代码1
Future future = longTimeMethod2();
//我们需要执行的代码2
Integer result = future.get();

需要返回结果的时候直接调用future.get()便能获取到返回值

四、异步流——Lambda表达式的实现(parallelStream)

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1,2,3,4,5,6);
    //若Lambda是串行执行,则应顺序打印
    list.parallelStream().forEach(System.out :: println);
    //Lambda有stream和parallelSteam(并行)
    return list.parallelStream().mapToInt(i -> i).sum();

    System.out.println("计算后的结果为"+result);
}
运行结果:
4
1
3
5
6
2
计算后的结果为21
事实证明是并行执行

五、消息队列

消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋,消息通讯,日志处理等问题场景,实现高性能,高可用,可伸缩和最终一致性;使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,RocketMQ等。

异步场景说明:例如用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式

串行流程图:

image.png

并行流程图:

image.png

并行场景可以在写入数据库后,发送mq消息,短信和邮件在接收到mq消息后自行处理。 与串行相比,并行可以提高时间处理能力,提高处理效率;不用互相等待。