Android 使用多个线程池执行器
Posted
技术标签:
【中文标题】Android 使用多个线程池执行器【英文标题】:Android using multiple threadpoolexecutors 【发布时间】:2017-06-28 16:21:02 【问题描述】:嘿,这是一个有趣的问题。我在我的 android 项目中使用了很多带有 sqlite 的 sql 操作。为此,我使用线程池来重用现有资源。线程池长这样:
final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(NUMBER_OF_CORES*2,NUMBER_OF_CORES*2,1L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(12,true),new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND),new RejectedThread(context));
public class PriorityThreadFactory implements ThreadFactory
private final int mThreadPriority;
public PriorityThreadFactory(int threadPriority)
mThreadPriority = threadPriority;
@Override
public Thread newThread(final Runnable runnable)
Runnable wrapperRunnable = new Runnable()
@Override
public void run()
try
android.os.Process.setThreadPriority(mThreadPriority);
catch (Throwable t)
runnable.run();
;
return new Thread(wrapperRunnable);
public class RejectedThread implements RejectedExecutionHandler
MyLogger myLogger;
public RejectedThread(Context context)
this.myLogger=new MyLogger(RejectedThread.class.getSimpleName(), context);
@Override
public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor)
this.myLogger.info("Execution rejected for: "+worker.toString());
我还在为我在数据库中进行的每个 CRUD(创建-读取-更新-删除)操作(由上面的线程池执行)创建一个新的 Runnable。这是问题,除了用于 sql 操作的线程池之外,我还需要一个线程池来执行记录器操作,以记录我制作的其余函数的系统行为。有没有办法防止任何粉碎/(资源不足),因为我正在使用两个或多个线程池执行器(分开分配,用于不同目的并且从不在另一个线程池执行器上执行线程池执行器) ?
【问题讨论】:
这一切似乎都是多余的。为什么记录器操作需要线程池?另外,为什么不能使用 AsyncTask 类中的现有执行程序?你有什么问题吗? 所有CRUD
操作无论如何都不会同步,这意味着运行线程池不是真正的优势吗?
[Okas] 所有这些日志都发送到服务,因此此操作始终在后台进行。我正在尝试完成类似:Firebase Crash Reporting (firebase.google.com/docs/crash) 但使用我的个人服务器且功能较少的事情。
[Mark Keen] 我认为我有很大的进步,因为所有的 crud 操作(对我来说)都是在我总是收到推送通知的地方完成的。根据我收到的消息,我的应用知道要执行什么操作,这样我的 ui 线程就空闲了。
对不起我的英语不好...
【参考方案1】:
我认为总的来说你的想法很好,但是你的实现有点低效。
试着自己回答这些问题:
为什么需要两个线程池? 您真的需要两个线程池吗? 为什么将 CORE 大小设置为 NUMBER_OF_CORES*2? 为什么将 MAX 大小设置为 NUMBER_OF_CORES*2? 您真的需要覆盖线程优先级吗?根据我的经验,上述并发症都不是真正必要的。
例如,在我的所有应用程序中,我使用BackgroundThreadPoster
类的单个实例来将工作卸载到后台线程。类很简单:
/**
* A single instance of this class should be used whenever we need to post anything to a (random) background thread.
*/
public class BackgroundThreadPoster
ExecutorService mExecutorService = Executors.newCachedThreadPool();
public void post(Runnable runnable)
mExecutorService.execute(runnable);
Executors.newCachedThreadPool()
返回的默认预配置实现就像魔术一样工作,我从未遇到过任何自定义其参数的需要。
可以在此处找到使用此方法的完整教程应用程序:https://github.com/techyourchance/android_mvc_tutorial
也许这对你也有用?
【讨论】:
感谢您的回答!以上是关于Android 使用多个线程池执行器的主要内容,如果未能解决你的问题,请参考以下文章
Android3.0以后,Asynctask在没开线程池的情况下会怎么排队执行
Android 对线程封装了:AsyncTask, HandlerThread和线程池。 有知道这三个如何选择吗?