业务场景:
在用户那,角色那变更后,要更新数据,因为更新要比较长时间,需要先返回结果(2:已接收待执行)。更新结束后,再返回值结果。
(执行结果. 0:执行失败 ; 1:执行成功; 2:已接收待执行)
处理1: 简单异步
使用 ExecutorService 异步
public void onCallback(JSONObject param) {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(() -> {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这边执行具体的方法
this.syncDealResult(param);
});
executor.shutdown();
}
public JSONObject dealResult(JSONObject params) {
// 先返回结果,然后异步执行
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);
// 处理完后推送结果
JSONObject param = new JSONObject();
param.put("logId", logId);
param.put("excRs", excRs);
// 推送结果
}
加 Thread.sleep(1000 * 10); 就明显看得出差别了。
如果是有多种异步执行,比如:A执行完后,B要做通知;C要入库;D要做统计,这时候要怎么处理呢?文章来源:https://www.toymoban.com/news/detail-493377.html
处理2:多个异步执行
IRoleCallback
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
/**
* AB角色异步调用接口
*
*/
public interface IRoleCallback {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @param param 结果
* @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("回调{}接口失败:", 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 {
// 执行更新操作
} catch (Exception e) {
e.printStackTrace();
excRs = "-1";
}
logger.info("update abRole finish callRecordId {}, excRs {}", logId, excRs);
// 处理完后推送结果
JSONObject param = new JSONObject();
param.put("logId", logId);
param.put("excRs", excRs);
logger.info("update role record {}", JSON.toJSONString(param));
// 推送结果
return "";
}
}
先返回结果后执行
@Resource
private RoleCallBackService roleCallBackService;
public JSONObject dealResult(JSONObject params) {
// 先返回结果,然后异步执行
try {
roleCallBackService.onCallback(params);
} catch (Exception e) {
e.printStackTrace();
}
JSONObject result = new JSONObject();
result.put("excRs", "2");
return result;
}
总结:
要先返回结果,后执行内容,需要使用异步的方式,用ExecutorService进行处理。如果是单个的,就直接调用比较简单。如果是多个的,就先要注册下,然后遍历去调用。 文章来源地址https://www.toymoban.com/news/detail-493377.html
到了这里,关于java 异步执行代码(先返回结果,后执行代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!