業(yè)務(wù)場(chǎng)景:
? ? ? ? 在用戶那,角色那變更后,要更新數(shù)據(jù),因?yàn)楦乱容^長(zhǎng)時(shí)間,需要先返回結(jié)果(2:已接收待執(zhí)行)。更新結(jié)束后,再返回值結(jié)果。
(執(zhí)行結(jié)果.?0:執(zhí)行失敗?; 1:執(zhí)行成功; 2:已接收待執(zhí)行)
處理1: 簡(jiǎn)單異步
使用?ExecutorService 異步
public void onCallback(JSONObject param) {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(() -> {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 這邊執(zhí)行具體的方法
this.syncDealResult(param);
});
executor.shutdown();
}
public JSONObject dealResult(JSONObject params) {
// 先返回結(jié)果,然后異步執(zhí)行
this.onCallback(params);
JSONObject result = new JSONObject();
result.put("excRs", "2");
return result;
}
public void syncDealResult(JSONObject params) {
logger.info("deal abRole param {}", JSON.toJSONString(params));
String logId = MapUtils.getString(params, "logId");
String excRs = "1";
try {
// 具體操作
} catch (Exception e) {
e.printStackTrace();
excRs = "-1";
}
logger.info("update abRole finish callRecordId {}, excRs {}", logId, excRs);
// 處理完后推送結(jié)果
JSONObject param = new JSONObject();
param.put("logId", logId);
param.put("excRs", excRs);
// 推送結(jié)果
}
加?Thread.sleep(1000 * 10); 就明顯看得出差別了。
如果是有多種異步執(zhí)行,比如:A執(zhí)行完后,B要做通知;C要入庫(kù);D要做統(tǒng)計(jì),這時(shí)候要怎么處理呢?文章來源:http://www.zghlxwxcb.cn/news/detail-493377.html
處理2:多個(gè)異步執(zhí)行
IRoleCallback
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
/**
* AB角色異步調(diào)用接口
*
*/
public interface IRoleCallback {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @param param 結(jié)果
* @return computed result
* @throws Exception if unable to compute a result
*/
Object call(JSONObject param) throws Exception;
/**
* unique name of callback
*
* @return callback name
*/
default String name() {
return StringUtils.uncapitalize(getClass().getSimpleName());
}
/**
* prior to callback 用于排序
*
* @return order
*/
default double order() {
return 1.0d;
}
}
RoleCallbackRegister
import java.util.*;
public class RoleCallbackRegister {
private static final Map<String, IRoleCallback> CALLBACKS = new HashMap<>();
public static boolean register(IRoleCallback callback) {
if (CALLBACKS.containsKey(callback.name())) {
return false;
}
CALLBACKS.put(callback.name(), callback);
return true;
}
public static List<IRoleCallback> getCallbacks() {
List<IRoleCallback> roleCallbacks = new ArrayList<>(CALLBACKS.values());
roleCallbacks.sort(Comparator.comparingDouble(IRoleCallback::order));
return roleCallbacks;
}
}
SpringUtils
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
AbstractRoleCallbackImpl
import com.web.work.common.support.SpringUtils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
public abstract class AbstractRoleCallbackImpl implements IRoleCallback, InitializingBean {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public Object call(JSONObject param) throws Exception {
return doCall(param);
}
protected abstract Object doCall(JSONObject param) throws Exception;
@Override
public String name() {
return StringUtils.uncapitalize(getClass().getSimpleName());
}
@Override
public void afterPropertiesSet() {
boolean register = RoleCallbackRegister.register(SpringUtils.getBean(this.getClass()));
if (!register) {
logger.error("register role callback name:{} failed.", name());
} else {
logger.info("register role callback name:{} succeed.", name());
}
}
}
RoleCallBackService
@Service
public class RoleCallBackService implements InitializingBean, DisposableBean {
private final static Logger logger = LoggerFactory.getLogger(RoleCallBackService.class);
private ThreadPoolExecutor pool;
public void onCallback(JSONObject param) {
pool.execute(() -> {
RoleCallbackRegister.getCallbacks().forEach(x -> {
try {
logger.info("call {}", x.name());
x.call(param);
} catch (Exception e) {
logger.error("回調(diào){}接口失?。?, x.name(), e);
}
});
});
}
@Override
public void afterPropertiesSet() {
int size = Runtime.getRuntime().availableProcessors() + 1;
pool = new ThreadPoolExecutor(size, size * 2, 300L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
}
@Override
public void destroy() throws Exception {
pool.shutdown();
}
}
RoleUpdateService
@Service
public class RoleUpdateService extends AbstractRoleCallbackImpl {
private final static Logger logger = LoggerFactory.getLogger(RoleUpdateService.class);
@Override
protected Object doCall(JSONObject params) throws Exception {
Thread.sleep(1000 * 10);
logger.info("deal abRole param {}", JSON.toJSONString(params));
String logId = MapUtils.getString(params, "logId");
String excRs = "1";
try {
// 執(zhí)行更新操作
} catch (Exception e) {
e.printStackTrace();
excRs = "-1";
}
logger.info("update abRole finish callRecordId {}, excRs {}", logId, excRs);
// 處理完后推送結(jié)果
JSONObject param = new JSONObject();
param.put("logId", logId);
param.put("excRs", excRs);
logger.info("update role record {}", JSON.toJSONString(param));
// 推送結(jié)果
return "";
}
}
先返回結(jié)果后執(zhí)行
@Resource
private RoleCallBackService roleCallBackService;
public JSONObject dealResult(JSONObject params) {
// 先返回結(jié)果,然后異步執(zhí)行
try {
roleCallBackService.onCallback(params);
} catch (Exception e) {
e.printStackTrace();
}
JSONObject result = new JSONObject();
result.put("excRs", "2");
return result;
}
總結(jié):
? ? ? ? 要先返回結(jié)果,后執(zhí)行內(nèi)容,需要使用異步的方式,用ExecutorService進(jìn)行處理。如果是單個(gè)的,就直接調(diào)用比較簡(jiǎn)單。如果是多個(gè)的,就先要注冊(cè)下,然后遍歷去調(diào)用。?文章來源地址http://www.zghlxwxcb.cn/news/detail-493377.html
到了這里,關(guān)于java 異步執(zhí)行代碼(先返回結(jié)果,后執(zhí)行代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!