Android如何調(diào)整線(xiàn)程調(diào)用棧大小
在常規(guī)的Android開(kāi)發(fā)過(guò)程中,隨著業(yè)務(wù)邏輯越來(lái)越復(fù)雜,調(diào)用棧可能會(huì)越來(lái)越深,難免會(huì)遇到調(diào)用棧越界的情況,這種情況下,就需要調(diào)整線(xiàn)程棧的大小。
當(dāng)然,主要還是增大線(xiàn)程棧大小,尤其是存在jni調(diào)用的情況下,C++層的棧開(kāi)銷(xiāo)有時(shí)候是非常恐怖的,比如說(shuō)遞歸調(diào)用。
這就需要分三種情況,主線(xiàn)程,自定義線(xiàn)程池,AsyncTask。
主線(xiàn)程的線(xiàn)程棧是沒(méi)有辦法進(jìn)行修改的,這個(gè)沒(méi)辦法處理。
針對(duì)線(xiàn)程池的情況,需要在創(chuàng)建線(xiàn)程的時(shí)候,調(diào)用構(gòu)造函數(shù)
public Thread(@RecentlyNullable ThreadGroup group, @RecentlyNullable Runnable target, @RecentlyNonNull String name, long stackSize)
通過(guò)設(shè)置stackSize參數(shù)來(lái)解決問(wèn)題。
參考代碼如下:
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");
// 工作線(xiàn)程堆棧大小調(diào)整為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;
}
}
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();
}
}
}
}
針對(duì)AsyncTask的情況,一般是通過(guò)調(diào)用
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params)
指定線(xiàn)程池來(lái)運(yùn)行,在特定的線(xiàn)程池中調(diào)整線(xiàn)程棧的大小。
參考代碼如下:
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:增加調(diào)用堆棧大小
- AsyncTask和線(xiàn)程池
以上就是Android如何調(diào)整線(xiàn)程調(diào)用棧大小的詳細(xì)內(nèi)容,更多關(guān)于Android 調(diào)整調(diào)用棧大小的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Flutter框架實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果
這篇文章主要介紹了Flutter框架實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果,Flutter框架中的Draggable部件,用于支持用戶(hù)通過(guò)手勢(shì)拖動(dòng),它是基于手勢(shì)的一種方式,可以使用戶(hù)可以在屏幕上拖動(dòng)指定的部件,下面我們來(lái)詳細(xì)了解一下2023-12-12
Android音頻系統(tǒng)AudioTrack使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android音頻系統(tǒng)AudioTrack的使用方法,如何使用AudioTrack進(jìn)行音頻播放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Android開(kāi)發(fā)之Picasso通過(guò)URL獲取用戶(hù)頭像的圓形顯示
這篇文章主要介紹了android開(kāi)發(fā)之Picasso通過(guò)URL獲取用戶(hù)頭像的圓形顯示,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-06-06
Android編程之文件讀寫(xiě)操作與技巧總結(jié)【經(jīng)典收藏】
這篇文章主要介紹了Android編程之文件讀寫(xiě)操作與技巧,結(jié)合實(shí)例形式總結(jié)分析了Android常見(jiàn)的文件與目錄的讀寫(xiě)操作,及相關(guān)函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
Kotlin基本類(lèi)型自動(dòng)裝箱一點(diǎn)問(wèn)題剖析
這篇文章主要剖析了Kotlin基本類(lèi)型自動(dòng)裝箱的一點(diǎn)問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
android利用handler實(shí)現(xiàn)打地鼠游戲
這篇文章主要為大家詳細(xì)介紹了android利用handler實(shí)現(xiàn)打地鼠游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11

