异步线程,多线程在项目启动时候执行方法

有时候项目需要去做一些初始化操作,那么不能在项目已经启动了去做操作,走定时任务,或者执行一些接口,或者mq,目前我感觉最好办法就是执行一个异步线程,或者启动一个线程池在项目启动的时候去执行这些业务逻辑,下面给出这两种写法。

如果不了解线程,或者是java线程池的可以先了解一下,我们平时写的代码都是单线程,就是一个方法走一次调用,多线程就是一个方法可以进行多个线程同时调用,使用多线程的时候记住,一定在使用完以后关闭线程,不然你的cpu就beng,电脑会卡掉。

1.ExecutorService 使用线程池去开启线程

package com.pactera.base.utlis;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PreDestroy;

import org.springframework.stereotype.Service;

@Service
public class ThreadPoolService {

    private static final ExecutorService pool = Executors.newFixedThreadPool(200);

    public void submit(Thread t) {
        pool.submit(t);
    }

    public void execute(Runnable r) {
        pool.execute(r);
    }

    @PreDestroy
    public void shutDown() {
        pool.shutdown();
    }
}

// 这是在项目启动的时候去走线程池启动一个线程执行初始化信息方法

@PostConstruct不是Spring提供的。是Java自己的注解。
Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。

/**
 * @author guoyunlong
 * @description 接入智慧园区云平台同步用户信息
 */
@Component
public class DataSynTask {

    @Autowired
    private ThreadPoolService threadPoolService;

    @Value("${userPark.appId}")
    private Long appId;

    @Value("${userPark.appKey}")
    private String appKey;

    @Value("${userPark.appSecret}")
    private String appSecret;

    @Value("${userPark.url}")
    private String curl;

    @Autowired
    private SyUserMapper syUserMapper;

    @Autowired
    private RecOrganizationMapper organizationMapper;

    @PostConstruct
    public void init() {
        threadPoolService.execute(new Thread() {
            @SneakyThrows
            @Override
            public void run() {
            	// 调用业务
                methodTask();
            }
        });
    }

    /**
     * 执行业务逻辑
     */
    public void methodTask() throws Exception {
   ------------
}

2.启用异步线程执初始化信息 实现Runnable 接口

在Application类上加上EnableAsync注解开启异步
在被调用的方法上面加上@Async,也可以直接在类上加此注解,会标识所有方法为异步方法
必须要加@EnableAsync注解
不能在同一类下调用@Async注解的方法,比如类1下有test1和test2方法,test2方法有@Async注解,不能直接这样test1调用test2,要把test2放到其他类中
@Async也可以打在类上,这样类下面的所有方法都是异步的(被其他类调用的时候),我们使用 @PostConstruct 它来实现


/**
 * 同步云平台用户信息
 *
 * @author gaoruiqiang
 * @since 2021-01-06
 */
@Component
public class DataSynTask implements Runnable {

    @Autowired
    private SpaceSysUsersMapper usersMapper;

    @Autowired
    private SpaceSysOrgMapper orgMapper;

    @Autowired
    private SpaceSysRoleMenuMapper roleMenuMapper;

    @Autowired
    private SpaceSysUserRoleMapper userRoleMapper;

    @PostConstruct
    public void init() {
        new Thread(this).start();
    }

    // 云平台用户信息
    String s = "1";

    @Override
    public void run() {
        synchronized(this) {
            while (true) {
                try {
                    if (s.isEmpty()) {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        methodTask(s);
                        return;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 执行业务逻辑
     */
    public void methodTask(String s) {

        SpaceSysUser spaceSysUser = usersMapper.selectByPrimaryKey(s);
        System.out.println("----------------" + spaceSysUser);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭优秀的笔记

你的支持就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值