- 任务调度管理任务的执行,因为特殊性,有些任务需要先进先出,排队进行,同时任务只能一个个执行
- 据我所知,了解三种方案:
- Handler,HandlerThread
- ExecutorService
- Action
- Handler,HandlerThread 任务需要在工作线程中HandlerThread中执行,通过Handler的发送消息和处理消息,保证顺序长时间执行,保证线程不会阻塞。
private Handler eventHandler = null;
HandlerThread handlerThread = new HandlerThread("WebSocketThread");
handlerThread.start();
eventHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
internalHandler.handleEvent(msg);
if (!externalHandlers.isEmpty()) {
for (IEventHandler handler : externalHandlers) {
handler.handleEvent(msg);
}
}
}
};
-
ExecutorService
通过封装ExecutorService 来实现单线程一个个顺序执行,它也可以实现并行执行,可以参看 Executors相关的工厂方法来确定.
public enum SingleExecutor {
INSTANCE;
ExecutorService executorService = Executors.newSingleThreadExecutor();
public ExecutorService getExecutorService() {
return executorService;
}
}
通过ExecutorService来submit执行Runnable,实现任务的执行,多个任务执行内部线程插入进行任务调度。
- 自定任务机制,比较麻烦,不建议使用。需要自己维护事件和线程,容易出错。
public class Executor implements LifecycleObserver,
Action.OnFinishedListener,
Action.OnReadyListener {
private static Executor sInstance = null;
private final IWSServer wsServer;
private final LinkedList<Action<?>> ongoingActions = new LinkedList<>();
private final List<Action<?>> pendingActions = new ArrayList<>();
private WorkThread curThread = null;
private Executor(IWSServer server) {
wsServer = server;
}
public static Executor getInstance(IWSServer server) {
if (sInstance == null) {
synchronized (Executor.class) {
if (sInstance == null) {
sInstance = new Executor(server);
}
}
}
return sInstance;
}
public void add(Action<?> action) {
if (action == null) {
return;
}
if (!action.isReady()) {
addPendingAction(action);
} else {
addOngoingAction(action);
}
}
/**
* 反馈
*
* @param response
*/
@Override
public void onFinished(String response) {
if (TextUtils.isEmpty(response)) {
return;
}
wsServer.sendMessage(response);
}
@Override
public void onReady(Action<?> action) {
if (!pendingActions.contains(action)) {
LogUtil.e("Invalid action in onReady");
return;
}
action.setOnReadyListener(null);
pendingActions.remove(action);
addOngoingAction(action);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void onDestroy() {
cancelThread();
}
/**
* 加入队列
*
* @param action
*/
private void addPendingAction(Action<?> action) {
pendingActions.add(action);
action.setOnReadyListener(this);
action.prepare(wsServer);
}
/**
* 正在进行
*
* @param action
*/
private void addOngoingAction(Action<?> action) {
synchronized (ongoingActions) {
ongoingActions.add(action);
}
if (!ongoingActions.isEmpty() && curThread == null) {
curThread = new WorkThread();
curThread.start();
}
}
private void cancelThread() {
if (curThread != null) {
curThread.cancel();
curThread = null;
}
}
private Action<?> popAction() {
synchronized (ongoingActions) {
return ongoingActions.isEmpty() ? null : ongoingActions.pop();
}
}
private void process(Action<?> action) {
action.execute();
}
private class WorkThread extends Thread {
private boolean isCancelled = false;
@Override
public void run() {
LogUtil.e("run work thread to process actions");
if (isCancelled) {
return;
}
Action<?> current;
while (!isCancelled && ((current = popAction()) != null)) {
current.setOnFinishedListener(Executor.this);
process(current);
}
LogUtil.e("finish work thread");
onFinish();
}
public void cancel() {
isCancelled = true;
}
public void onFinish() {
curThread = null;
}
}
}
Action类
public abstract class Action<T extends WSMessage<?>> {
protected T request;
protected OnFinishedListener onFinishedListener;
protected OnReadyListener onReadyListener;
public Action(T wsMessage) {
request = wsMessage;
}
public abstract void execute();
public abstract boolean isReady();
public void setOnFinishedListener(OnFinishedListener listener) {
onFinishedListener = listener;
}
public void setOnReadyListener(OnReadyListener listener) {
onReadyListener = listener;
}
protected void notifyFinish(String response) {
if (onFinishedListener != null) {
onFinishedListener.onFinished(response);
}
}
protected void prepare(IWSServer server) {
}
public interface OnReadyListener {
void onReady(Action<?> action);
}
public interface OnFinishedListener {
void onFinished(String response);
}
}