当前位置: 首页 > article >正文

顺序执行的Runnable队列

当一个任务需要放到子线程执行时,一般new Runnable就可以了。

可有的时候需要保证Runnable按顺序执行,比如连续收到了推送,这时候可以用子线程队列

以下是EventBus 3.2.0里面的实现方式,抽取出来做技术调研

1.BackgroundPoster

/*
 * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.commonsdk.async;

import android.util.Log;

/**
 * Posts events in background.
 *
 * @author Markus
 */
final public class BackgroundPoster implements Runnable {

    private static BackgroundPoster mInstance = null;

    public static BackgroundPoster getInstance() {
        if (mInstance == null) {
            mInstance = new BackgroundPoster();
        }
        return mInstance;
    }

    private final PendingPostQueue queue;

    private volatile boolean executorRunning;

    private BackgroundPoster() {
        queue = new PendingPostQueue();
    }

    public void enqueue(Poster subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!executorRunning) {
                executorRunning = true;
                CXThreadPoolManager.getThreadPool().submit(this);
            }
        }
    }

    @Override
    public void run() {
        try {
            try {
                while (true) {
                    PendingPost pendingPost = queue.poll(1000);
                    if (pendingPost == null) {
                        synchronized (this) {
                            // Check again, this time in synchronized
                            pendingPost = queue.poll();
                            if (pendingPost == null) {
                                executorRunning = false;
                                return;
                            }
                        }
                    }
                    pendingPost.subscription.invoke(pendingPost.event);
                }
            } catch (InterruptedException e) {
                Log.e("BackgroundPoster", Thread.currentThread().getName() + " was interruppted", e);
            }
        } finally {
            executorRunning = false;
        }
    }

}

2.PendingPost

/*
 * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.commonsdk.async;

import java.util.ArrayList;
import java.util.List;

final class PendingPost {
    private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();

    Object event;
    Poster subscription;
    PendingPost next;

    private PendingPost(Object event, Poster subscription) {
        this.event = event;
        this.subscription = subscription;
    }

    static PendingPost obtainPendingPost(Poster subscription, Object event) {
        synchronized (pendingPostPool) {
            int size = pendingPostPool.size();
            if (size > 0) {
                PendingPost pendingPost = pendingPostPool.remove(size - 1);
                pendingPost.event = event;
                pendingPost.subscription = subscription;
                pendingPost.next = null;
                return pendingPost;
            }
        }
        return new PendingPost(event, subscription);
    }

    static void releasePendingPost(PendingPost pendingPost) {
        pendingPost.event = null;
        pendingPost.subscription = null;
        pendingPost.next = null;
        synchronized (pendingPostPool) {
            // Don't let the pool grow indefinitely
            if (pendingPostPool.size() < 10000) {
                pendingPostPool.add(pendingPost);
            }
        }
    }

}

3.PendingPostQueue

package com.commonsdk.async;

final class PendingPostQueue {
    private PendingPost head;
    private PendingPost tail;

    synchronized void enqueue(PendingPost pendingPost) {
        if (pendingPost == null) {
            throw new NullPointerException("null cannot be enqueued");
        }
        if (tail != null) {
            tail.next = pendingPost;
            tail = pendingPost;
        } else if (head == null) {
            head = tail = pendingPost;
        } else {
            throw new IllegalStateException("Head present, but no tail");
        }
        notifyAll();
    }

    synchronized PendingPost poll() {
        PendingPost pendingPost = head;
        if (head != null) {
            head = head.next;
            if (head == null) {
                tail = null;
            }
        }
        return pendingPost;
    }

    synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
        if (head == null) {
            wait(maxMillisToWait);
        }
        return poll();
    }

}

4.Poster

/*
 * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.commonsdk.async;

public interface Poster {

    void invoke(Object event);
}

5.使用方法

package cn.platform.util;

import android.content.Intent;

import com.commonsdk.async.BackgroundPoster;
import com.commonsdk.async.Poster;

public class PlatformClient implements Poster {
    private static PlatformClient mPlatformClient = null;

    public static PlatformClient getInstance() {
        if (mPlatformClient == null) {
            mPlatformClient = new PlatformClient();
        }
        return mPlatformClient;
    }

    public void notifyAction(Intent intent) {
        //调用此接口添加进队列
        BackgroundPoster.getInstance().enqueue(this, intent);
    }

    @Override
    public void invoke(Object object) {
        Intent intent;
        if (object != null && object instanceof Intent) {
            intent = (Intent) object;
        } else {
            return;
        }
        if (intent == null || intent.getAction() == null) {
            return;
        }
        switch (intent.getAction()) {
            case "platform_push_command_msg_arrived": 
                break;
            default:
                break;
        }
    }
}


http://www.kler.cn/a/351159.html

相关文章:

  • 左神算法基础提升--1
  • 12 USART串口通讯
  • 【AIGC-ChatGPT进阶提示词指令】智慧母婴:打造基于成长树的儿童发展引导系统
  • Require:利用MySQL binlog实现闪回操作
  • ANSYS Fluent学习笔记(七)求解器四部分
  • Microsoft
  • 【Java 22 | 11】 深入解析Java 22 : String API 增强特性
  • 【Redis】Zset类型常用命令
  • AWS账号与亚马逊账号的关系解析
  • 【网络安全】JSONP劫持原理及攻击实战
  • 鸿蒙系统开发快速入门教程
  • 【论文速读】Prompt Tuning:The Power of Scale for Parameter-Effificient Prompt Tuning
  • 大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
  • 鸿蒙--自定义系统级弹层
  • ansible————playbook
  • N9305高品质mp3音频语音芯片ic在早教故事机的应用方案
  • 再Android10上实现检测AHD摄像头是否接入
  • RK3568平台开发系列讲解(调试篇)CGroup(Control Group)之CPU资源
  • 【python + Redis】hash值查增删
  • 【AI声音克隆本地整合包及教程】第二代GPT-SoVITS V2:声音克隆的新境界
  • 02-GIT
  • Vue2项目-自定义指令
  • Windows远程桌面到Ubuntu
  • 圈子系统该如何安装?前端UNI后端PHP论坛小程序源码 圈子小程序源码
  • Vxe UI vue vxe-table grid 如何滚动、定位到指定行或列
  • Python中的pool.map函数:高效处理数据与计算任务