1. 程式人生 > 其它 >非同步執行緒,多執行緒在專案啟動時候執行方法

非同步執行緒,多執行緒在專案啟動時候執行方法

技術標籤:筆記多執行緒java

有時候專案需要去做一些初始化操作,那麼不能在專案已經啟動了去做操作,走定時任務,或者執行一些介面,或者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);
    }
}