我的 Android 应用程序用于工业环境中的数据收集 - 全职员工使用该应用程序进行许多观察(照片、地理标签、文本等),然后在 wifi 可用时批量上传。
我使用 Amazon 的 Android SDK 执行批量 S3 上传 - 在后台,这个库在每次上传时使用一个线程池线程,偶尔我会遇到 RejectedExecutionException。我很好奇我是否能以更有弹性的方式处理这个问题......
请注意,我的代码不执行并行上传,我使用单个线程依次为每张照片调用 s3.transfer.TransferManager.upload(),等待完成,然后继续。因此,在任何给定时间,这里应该只有 ~2 个相关线程 - 一个用于我的代码,一个用于 Amazon 调度的线程。
但是当线程池没有更多空间时,我的用户偶尔会遇到 RejectedExecutionException:
java.util.concurrent.RejectedExecutionException: pool=0/10, queue=0
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1961)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1315)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:107)
at com.amazonaws.services.s3.transfer.internal.UploadMonitor.<init>(Unknown Source)
at com.amazonaws.services.s3.transfer.TransferManager.upload(Unknown Source)
at com.amazonaws.services.s3.transfer.TransferManager.upload(Unknown Source)
at com.amazonaws.services.s3.transfer.TransferManager.upload(Unknown Source)
查看崩溃报告中包含的所有其他线程堆栈,我想知道其他 AsyncTask 是否只是过去的上传,还没有机会清理?例如,我看到很多:
java.lang.Object.wait(Native Method)
java.lang.Thread.parkFor(Thread.java:1424)
java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
sun.misc.Unsafe.park(Unsafe.java:337)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
java.lang.Thread.run(Thread.java:1019)
这些线程是否可能只是需要一个清理的机会?如果是这样,是否有一种相对简单的机制可以在可预测的时间/风险内完成此操作,以便我可以继续批量上传?
我想知道我的主上传线程上的 thread.sleep(0) 的(概念)等价物是否会给池一个清理的机会,然后我可以重试上传?
我将不胜感激任何想法或经验。我无法在内部复制它,而且它是不可预测的,所以我的实验能力在这里受到限制......
谢谢。