提交任务,线程池提供RejectedExecutionException [英] Submitting tasks to a thread-pool gives RejectedExecutionException

查看:2206
本文介绍了提交任务,线程池提供RejectedExecutionException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个社交游戏运行的大多是本地code中的Andr​​oid NDK。游戏中有3个主要NDK pthreads的:

I am working on a social game running mostly native code in Android NDK. The game has 3 main ndk pthreads:

  1. 在一个游戏线程
  2. 服务器通信线程
  3. 主渲染线程(通过Renderer.onRender称呼)

除此之外,在Java方面,我们使用AdWhirl它通过自己的 ScheduledExecutorService的派生自己的线程,但我们包裹在每次调用日程安排,提交,后,启动等与try-catch块赶上 RejectedExecutionException 。然而,dreadly RejectedExecutionException 还是发生在我们每个提交的新版本。

Other than that, on java side, we are using AdWhirl which spawns their own thread through their own ScheduledExecutorService, but we have wrapped every call to "schedule", "submit", "post", "start" etc with try-catch block to catch the RejectedExecutionException. However, the dreadly RejectedExecutionException still occurs on every new versions we submitted.

从Android Market中的堆栈跟踪离开几乎没有任何更多的线索,我和我们的QA部门也觉得很难确定,因为它测试过程中几乎没有出现问题(仅适用于我们的用户报告的崩溃)。它影响我们的用户中只有一小部分,但仍然是每周超过7000崩溃(与大量的安装基础的小部分相比)

The stack trace from Android Market leaves hardly any more clues for me and our QA department also find it difficult to pinpoint the problem as it hardly occur during test (only our users reported crash). It affects only a small portion of our users but still it is more than 7,000 crashes per week (small portion compared with high number of install base)

java.util.concurrent.RejectedExecutionException
at         java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1876)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:774)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4632)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

    java.util.concurrent.RejectedExecutionException: pool=128/128, queue=10/10
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 android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)

    java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1876)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:774)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

推荐答案

虽然你当然应该尽量让事情尽可能地有效,没有任何限制线程的数量,你是允许运行,它一切都取决于你如何组织你的code。

解决方案

的ThreadPoolExecutor 类的<​​em>非常的有据可查的,是在这里你看到的问题是始发。我想建议通过它阅读,看看

While you should of course try to keep things as efficient as possible, there is no arbitrary limit to the number of threads you are "allowed" to run, it all depends on how you structure your code.

首先我猜你正在构建这个与蚂蚁并没有在你的javac节点上使用这些参数:

The ThreadPoolExecutor class is extremely well documented, and is where the issue you're seeing is originating. I would recommend reading through it, check out

To start with I'm guessing that you're building this with Ant and aren't using these parameters on your javac node:

如果不是这样,你显然使用混淆器是一个通常是一个堆栈跟踪中最重要的部分,而不是简单地输出其原因:

<javac debug="true" debuglevel="lines,vars,source" />

Either that or the obfuscator you are apparently using are the reason that what would normally be the most important part of a stack trace is instead simply outputting:

这是目前ICS 4.0.4源ThreadPoolExecutor.AbortPolicy,你可以看到它基本上是一个包罗万象的总是会抛出异常:

c.onProgressUpdate(Unknown Source)

This is the current ICS 4.0.4 source for ThreadPoolExecutor.AbortPolicy, as you can see it's basically a catch-all that always throws an exception:

此外,你会发现在DefaultHandler的ThreadPoolExecutor的顶部声明

Additionally, you'll find the defaultHandler declared at the top of ThreadPoolExecutor:

private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

所以最后,如果你的默认构造函数的ThreadPoolExecutor:

So finally, if you look at the default Constructor for ThreadPoolExecutor:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}

您会看到,它的使用实例化本身是 AbortPolicy 类,这是它的默认值 RejectedExecutionHandler

You'll see that it's instantiating itself using it's AbortPolicy class, which is its default RejectedExecutionHandler.

的ThreadPoolExecutor 还包括其他几个 RejectedExecutionHandler 的子类,你可以设置为默认值,如:

ThreadPoolExecutor also includes several other RejectedExecutionHandler subclasses that you could set as the default, such as:

  /**
 * A handler for rejected tasks that silently discards the
 * rejected task.
 */
public static class DiscardPolicy implements RejectedExecutionHandler {
    /**
     * Creates a {@code DiscardPolicy}.
     */
    public DiscardPolicy() { }

    /**
     * Does nothing, which has the effect of discarding task r.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}

另外3 的ThreadPoolExecutor 构造包括处理器选项,这样你既可以使用不同的处理程序创建它的一个实例,或者创建你自己的子类,类似这样的:

The other 3 ThreadPoolExecutor constructors include a handler option, so you could either create an instance of it using a different handler, or create you're own subclass, similar to this:

package com.justinbuser;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class NoThrowThreadPool extends ThreadPoolExecutor {

    private static final RejectedExecutionHandler defaultHandler = new AdoptPolicy();

    public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
        setRejectedExecutionHandler(defaultHandler);
    }

    public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
            ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);
    }

    public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
            RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
    }

    public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
            ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);
    }

    public static class AdoptPolicy extends ThreadPoolExecutor.AbortPolicy {

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()).printStackTrace();
        }
    }
}

这篇关于提交任务,线程池提供RejectedExecutionException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆