异步调用和同步调用 及 spring的@Async注解 您所在的位置:网站首页 java异步方法调用异步方法 异步调用和同步调用 及 spring的@Async注解

异步调用和同步调用 及 spring的@Async注解

#异步调用和同步调用 及 spring的@Async注解| 来源: 网络整理| 查看: 265

1. 何为异步调用?

在解释异步调用之前,我们先来看同步调用的定义; 同步调用就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕,而是继续执行下面的流程。 例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。

2. 常规的异步调用处理方式

在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。

3. @Async介绍

在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

分为不带参数的异步调用;带参数的异步调用;调用返回Future的异步线程

4. @Async调用中的事务处理机制

在@Async标注的方法,同时也适用了@Transactional进行了标注;在其调用数据库操作之时,将无法产生事务管理的控制,原因就在于其是基于异步处理的操作。 那该如何给这些操作添加事务管理呢?可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional注解。 例如: 方法A,使用了@Async/@Transactional来标注,但是无法产生事务控制的目的。 方法B,使用了@Async来标注, B中调用了C、D,C/D分别使用@Transactional做了标注,则可实现事务控制的目的。

5. 配合使用@EnableAsync

@EnableAsync 在启动类或者Control类加上 @EnableAsync 注解

@EnableAsync注解的意思是可以异步执行,就是开启多线程的意思。可以标注在方法、类上。@Async所修饰的函数不要定义为static类型,这样异步调用不会生效。 如下:

@SpringBootApplication @EnableAsync public class Application { public static void main( String[] args ) { SpringApplication.run(Application.class, args); } }

或者:

@EnableAsync @RestController public class HelloController { @Autowired TestAsyncService testAsyncService; } 6. 举例:

两张表:user_info和order_table 插入user_info数据时候用同步,插入order_table用异步。

在controller类中创建一个方法 同时保存user_info和order_table表。保存order_table用异步(对应service方法中用@Async标注)

(1)domain文件夹中创建Entity类

package com.cfj.ceshi.async.domain; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="order_table") public class OrderTable implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name = "order_name") private String orderName; @Column(name = "user_id") private Integer userId; @Column(name = "create_date") private Date createDate; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } } package com.cfj.ceshi.async.domain; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="user_info") public class UserInfo implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String userName; private String age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "UserInfo [id=" + id + ", userName=" + userName + ", age=" + age + "]"; } }

(2)创建repository层操作数据库。如果是普通保存方法,只需要接口继承JpaRepository,不需要写具体方法

package com.cfj.ceshi.async.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.cfj.ceshi.async.domain.OrderTable; public interface OrderRepository extends JpaRepository { } package com.cfj.ceshi.async.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.cfj.ceshi.async.domain.UserInfo; public interface UserRepository extends JpaRepository { }

(3)service层 其中order的实现层保存方法加上@Async

package com.cfj.ceshi.async.service; public interface OrderService { public void saveOrder(Integer UserId,String name); } package com.cfj.ceshi.async.service; import java.util.List; import com.cfj.ceshi.async.domain.UserInfo; public interface UserService { public Integer save(UserInfo user); } package com.cfj.ceshi.async.service.impl; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import com.cfj.ceshi.async.domain.OrderTable; import com.cfj.ceshi.async.repository.OrderRepository; import com.cfj.ceshi.async.service.OrderService; @Service public class OrderServiceImpl implements OrderService { @Autowired OrderRepository orderRepository; /** * 异步保存 */ @Async @Override public void saveOrder(Integer UserId,String name) { System.out.println("UserId:"+UserId); System.out.println("=====" + Thread.currentThread().getName() + "========="); OrderTable orderTable = new OrderTable(); orderTable.setOrderName(name+"订单"); orderTable.setUserId(UserId); orderTable.setCreateDate(new Date()); orderRepository.save(orderTable); } } package com.cfj.ceshi.async.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.cfj.ceshi.async.domain.UserInfo; import com.cfj.ceshi.async.repository.UserRepository; import com.cfj.ceshi.async.service.UserService; @Service @Transactional public class UserServiceImpl implements UserService{ @Autowired private UserRepository userRepository; @Override public Integer save(UserInfo user) { System.out.println("=====" + Thread.currentThread().getName() + "========="); return userRepository.save(user).getId(); } }

(4) control层,control类中添加@EnableAsync注解

package com.cfj.ceshi.async.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.cfj.ceshi.async.domain.UserInfo; import com.cfj.ceshi.async.service.OrderService; import com.cfj.ceshi.async.service.UserService; @EnableAsync @RestController @RequestMapping("/tesasyc") public class AsycWeb { @Autowired UserService userService; @Autowired OrderService orderService; /** * 请使用 postman测试 方式选择post http://localhost:8081/tesasyc/save-one * body 中选择form-data 或者x-wwww-form-urlencoded 输入对应键值对 * @param name * @param age * @return */ @PostMapping(value = "/save-one") //相当于@RequestMapping(value = "/save-one", method = RequestMethod.POST) public String postOne(String name,String age) { UserInfo user = new UserInfo(); user.setUserName(name); user.setAge(age); Integer id = userService.save(user); orderService.saveOrder(id,name); return id.toString(); } }

控制台输出如下: 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有