gpt4 book ai didi

android - 将任务提交到线程池会产生 RejectedExecutionException

转载 作者:IT老高 更新时间:2023-10-28 23:20:46 26 4
gpt4 key购买 nike

我正在开发一款在 Android NDK 中运行大部分原生代码的社交游戏。游戏有 3 个主要的 ndk pthreads:

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

除此之外,在 java 端,我们使用 AdWhirl,它通过自己的 ScheduledExecutorService 生成自己的线程,但我们已经包装了对“schedule”、“submit”、“post”的每个调用, "start"等使用 try-catch block 来捕获 RejectedExecutionException。然而,可怕的 RejectedExecutionException 仍然出现在我们提交的每个新版本上。

Android Market 的堆栈跟踪几乎没有给我留下任何线索,我们的 QA 部门也发现很难查明问题,因为它在测试期间几乎没有发生(只有我们的用户报告了崩溃)。它只影响我们的一小部分用户,但每周仍有超过 7,000 次崩溃(与大量安装基数相比,这是一小部分)

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)

最佳答案

虽然您当然应该尽量保持效率,但“允许”运行的线程数没有任意限制,这完全取决于您如何构建代码。

ThreadPoolExecutor非常有据可查,是您看到的问题的根源。我会recommend reading through it , 看看

首先我猜你是用 Ant 构建的,并且没有在你的 javac 节点上使用这些参数:

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

无论是那个还是您显然使用的混淆器都是堆栈跟踪中通常最重要的部分只是简单地输出的原因:

c.onProgressUpdate(Unknown Source)

这是 ThreadPoolExecutor.AbortPolicy 的当前 ICS 4.0.4 源代码,您可以看到它基本上是一个总能抛出异常的包罗万象:

 /**
* A handler for rejected tasks that throws a
* {@code RejectedExecutionException}.
*/

public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }

/**
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always.
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}

此外,您会发现在 ThreadPoolExecutor 顶部声明的 defaultHandler:

private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

最后,如果您查看 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

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

  /**
* 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 构造函数包含一个处理程序选项,因此您可以使用不同的处理程序创建它的实例,或者创建自己的子类,类似于:

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();
}
}
}

关于android - 将任务提交到线程池会产生 RejectedExecutionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7788672/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com