我是靠谱客的博主 寒冷蛋挞,这篇文章主要介绍Android如何调整线程调用栈大小,现在分享给大家,希望可以做个参考。

在常规的Android开发过程中,随着业务逻辑越来越复杂,调用栈可能会越来越深,难免会遇到调用栈越界的情况,这种情况下,就需要调整线程栈的大小。

当然,主要还是增大线程栈大小,尤其是存在jni调用的情况下,C++层的栈开销有时候是非常恐怖的,比如说递归调用。

这就需要分三种情况,主线程,自定义线程池,AsyncTask。

主线程的线程栈是没有办法进行修改的,这个没办法处理。

针对线程池的情况,需要在创建线程的时候,调用构造函数

复制代码
1
public Thread(@RecentlyNullable ThreadGroup group, @RecentlyNullable Runnable target, @RecentlyNonNull String name, long stackSize)

通过设置stackSize参数来解决问题。

参考代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import android.support.annotation.NonNull; import android.util.Log; import java.util.concurrent.ThreadFactory; /** * A ThreadFactory implementation which create new threads for the thread pool. */ public class SimpleThreadFactory implements ThreadFactory { private static final String TAG = "SimpleThreadFactory"; private final static ThreadGroup group = new ThreadGroup("SimpleThreadFactoryGroup"); // 工作线程堆栈大小调整为2MB private final static int workerStackSize = 2 * 1024 * 1024; @Override public Thread newThread(@NonNull final Runnable runnable) { final Thread thread = new Thread(group, runnable, "PoolWorkerThread", workerStackSize); // A exception handler is created to log the exception from threads thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(@NonNull Thread thread, @NonNull Throwable ex) { Log.e(TAG, thread.getName() + " encountered an error: " + ex.getMessage()); } }); return thread; } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import android.support.annotation.AnyThread; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * A Singleton thread pool */ public class ThreadPool { private static final String TAG = "ThreadPool"; private static final int KEEP_ALIVE_TIME = 1; private static volatile ThreadPool sInstance = null; private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); private final ExecutorService mExecutor; private final BlockingQueue<Runnable> mTaskQueue; // Made constructor private to avoid the class being initiated from outside private ThreadPool() { // initialize a queue for the thread pool. New tasks will be added to this queue mTaskQueue = new LinkedBlockingQueue<>(); Log.d(TAG, "Available cores: " + NUMBER_OF_CORES); mExecutor = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, TimeUnit.SECONDS, mTaskQueue, new SimpleThreadFactory()); } @NonNull @AnyThread public static ThreadPool getInstance() { if (null == sInstance) { synchronized (ThreadPool.class) { if (null == sInstance) { sInstance = new ThreadPool(); } } } return sInstance; } private boolean isThreadPoolAlive() { return (null != mExecutor) && !mExecutor.isTerminated() && !mExecutor.isShutdown(); } @Nullable @AnyThread public <T> Future<T> submitCallable(@NonNull final Callable<T> c) { synchronized (this) { if (isThreadPoolAlive()) { return mExecutor.submit(c); } } return null; } @Nullable @AnyThread public Future<?> submitRunnable(@NonNull final Runnable r) { synchronized (this) { if (isThreadPoolAlive()) { return mExecutor.submit(r); } } return null; } /* Remove all tasks in the queue and stop all running threads */ @AnyThread public void shutdownNow() { synchronized (this) { mTaskQueue.clear(); if ((!mExecutor.isShutdown()) && (!mExecutor.isTerminated())) { mExecutor.shutdownNow(); } } } }

针对AsyncTask的情况,一般是通过调用

复制代码
1
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params)

指定线程池来运行,在特定的线程池中调整线程栈的大小。

参考代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import android.os.AsyncTask; import android.support.annotation.AnyThread; import android.support.annotation.NonNull; import android.util.Log; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public abstract class AsyncTaskEx<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { private static final String TAG = "AsyncTaskEx"; private static final int KEEP_ALIVE_TIME = 1; private static volatile ThreadPool sInstance = null; private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); private final ExecutorService mExecutor; private final BlockingQueue<Runnable> mTaskQueue; public AsyncTaskEx() { // initialize a queue for the thread pool. New tasks will be added to this queue mTaskQueue = new LinkedBlockingQueue<>(); Log.d(TAG, "Available cores: " + NUMBER_OF_CORES); mExecutor = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, TimeUnit.SECONDS, mTaskQueue, new SimpleThreadFactory()); } public AsyncTask<Params, Progress, Result> executeAsync(@NonNull final Params... params) { return super.executeOnExecutor(mExecutor, params); } /* Remove all tasks in the queue and stop all running threads */ @AnyThread public void shutdownNow() { synchronized (this) { mTaskQueue.clear(); if ((!mExecutor.isShutdown()) && (!mExecutor.isTerminated())) { mExecutor.shutdownNow(); } } } }

参考链接

  • Increase AsyncTask stack size?
  • StackOverFlowError: Stack size 1036KB in AsyncTask
  • Android:增加调用堆栈大小
  • AsyncTask和线程池

以上就是Android如何调整线程调用栈大小的详细内容,更多关于Android 调整调用栈大小的资料请关注靠谱客其它相关文章!

最后

以上就是寒冷蛋挞最近收集整理的关于Android如何调整线程调用栈大小的全部内容,更多相关Android如何调整线程调用栈大小内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(169)

评论列表共有 0 条评论

立即
投稿
返回
顶部