這篇文章給大家介紹怎么在Java中按時間梯度異步回調(diào)接口,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
我們提供的服務有:成都網(wǎng)站設計、做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、碭山ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的碭山網(wǎng)站制作公司
用到的技術如下:
?http請求庫,retrofit2
?隊列,LinkedBlockingQueue
?調(diào)度線程池,ScheduledExecutorService

3. 主要代碼說明
3.1 回調(diào)時間梯度的策略設計
采用枚舉來對策略規(guī)則進行處理,便于代碼上的維護,該枚舉設計三個參數(shù),級別、回調(diào)間隔、回調(diào)次數(shù);
/**
* 回調(diào)策略
*/
public enum CallbackType {
//等級1,10s執(zhí)行3次
SECONDS_10(1, 10, 3),
//等級2,30s執(zhí)行2次
SECONDS_30(2, 30, 2),
//等級3,60s執(zhí)行2次
MINUTE_1(3, 60, 2),
//等級4,5min執(zhí)行1次
MINUTE_5(4, 300, 1),
//等級5,30min執(zhí)行1次
MINUTE_30(5, 30*60, 1),
//等級6,1h執(zhí)行2次
HOUR_1(6, 60*60, 1),
//等級7,3h執(zhí)行2次
HOUR_3(7, 60*60*3, 1),
//等級8,6h執(zhí)行2次
HOUR_6(8, 60*60*6, 1);
//級別
private int level;
//回調(diào)間隔時間 秒
private int intervalTime;
//回調(diào)次數(shù)
private int count;
}3.2 數(shù)據(jù)傳輸對象設計
聲明抽象父類,便于其他對象調(diào)用傳輸繼承。
/**
* 消息對象父類
*/
public abstract class MessageInfo {
//開始時間
private long startTime;
//更新時間
private long updateTime;
//是否回調(diào)成功
private boolean isSuccess=false;
//回調(diào)次數(shù)
private int count=0;
//回調(diào)策略
private CallbackType callbackType;
}要傳輸?shù)膶ο螅^承消息父類;
/**
* 工單回調(diào)信息
*/
public class WorkOrderMessage extends MessageInfo {
//車架號
private String vin;
//工單號
private String workorderno;
//工單狀態(tài)
private Integer status;
//工單原因
private String reason;
//操作用戶
private Integer userid;
}3.3 調(diào)度線程池的使用
//聲明線程池,大小為16
private ScheduledExecutorService pool = Executors.newScheduledThreadPool(16);
...略
while (true){
//從隊列獲取數(shù)據(jù),交給定時器執(zhí)行
try {
WorkOrderMessage message = MessageQueue.getMessageFromNext();
long excueTime = message.getUpdateTime()+message.getCallbackType().getIntervalTime()* 1000;
long t = excueTime - System.currentTimeMillis();
if (t/1000 < 5) {//5s之內(nèi)將要執(zhí)行的數(shù)據(jù)提交給調(diào)度線程池
System.out.println("MessageHandleNext-滿足定時器執(zhí)行條件"+JSONObject.toJSONString(message));
pool.schedule(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
remoteCallback(message);
return true;
}
}, t, TimeUnit.MILLISECONDS);
}else {
MessageQueue.putMessageToNext(message);
}
} catch (InterruptedException e) {
System.out.println(e);
}
}3.4 retrofit2的使用,方便好用。
具體可查看官網(wǎng)相關文檔進行了解,用起來還是比較方便的。http://square.github.io/retrofit/
retrofit初始化:
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitHelper {
private static final String HTTP_URL = "http://baidu.com/";
private static Retrofit retrofit;
public static Retrofit instance(){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(HTTP_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}如果需要修改超時時間,連接時間等可以這樣初始話,Retrofit采用OkHttpClient
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import java.util.concurrent.TimeUnit;
public class RetrofitHelper {
private static final String HTTP_URL = "http://baidu.com/";
private static Retrofit retrofit;
public static Retrofit instance(){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(HTTP_URL)
.client(new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)//連接時間
.readTimeout(30, TimeUnit.SECONDS)//讀時間
.writeTimeout(30, TimeUnit.SECONDS)//寫時間
.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}Retrofit使用通過接口調(diào)用,要先聲明一個接口;
import com.alibaba.fastjson.JSONObject;
import com.woasis.callbackdemo.bean.WorkOrderMessage;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface WorkOrderMessageInterface {
@POST("/api")
Call<JSONObject> updateBatteryInfo(@Body WorkOrderMessage message);
}接口和實例對象準備好了,接下來就是調(diào)用;
private void remoteCallback(WorkOrderMessage message){
//實例接口對象
WorkOrderMessageInterface workOrderMessageInterface = RetrofitHelper.instance().create(WorkOrderMessageInterface.class);
//調(diào)用接口方法
Call<JSONObject> objectCall = workOrderMessageInterface.updateBatteryInfo(message);
System.out.println("遠程調(diào)用執(zhí)行:"+new Date());
//異步調(diào)用執(zhí)行
objectCall.enqueue(new Callback<JSONObject>() {
@Override
public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
System.out.println("MessageHandleNext****調(diào)用成功"+Thread.currentThread().getId());
message.setSuccess(true);
System.out.println("MessageHandleNext-回調(diào)成功"+JSONObject.toJSONString(message));
}
@Override
public void onFailure(Call<JSONObject> call, Throwable throwable) {
System.out.println("MessageHandleNext++++調(diào)用失敗"+Thread.currentThread().getId());
//失敗后再將數(shù)據(jù)放入隊列
try {
//對回調(diào)策略初始化
long currentTime = System.currentTimeMillis();
message.setUpdateTime(currentTime);
message.setSuccess(false);
CallbackType callbackType = message.getCallbackType();
//獲取等級
int level = CallbackType.getLevel(callbackType);
//獲取次數(shù)
int count = CallbackType.getCount(callbackType);
//如果等級已經(jīng)最高,則不再回調(diào)
if (CallbackType.HOUR_6.getLevel() == callbackType.getLevel() && count == message.getCount()){
System.out.println("MessageHandleNext-等級最高,不再回調(diào), 線下處理:"+JSONObject.toJSONString(message));
}else {
//看count是否最大,count次數(shù)最大則增加level
if (message.getCount()<callbackType.getCount()){
message.setCount(message.getCount()+1);
}else {//如果不小,則增加level
message.setCount(1);
level += 1;
message.setCallbackType(CallbackType.getTypeByLevel(level));
}
MessageQueue.putMessageToNext(message);
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("MessageHandleNext-放入隊列數(shù)據(jù)失敗");
}
}
});
}3.5結果實現(xiàn)

關于怎么在Java中按時間梯度異步回調(diào)接口就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
新聞標題:怎么在Java中按時間梯度異步回調(diào)接口
分享鏈接:http://chinadenli.net/article20/gegejo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供關鍵詞優(yōu)化、網(wǎng)站排名、商城網(wǎng)站、App設計、建站公司、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)