Android如何調(diào)整線程調(diào)用棧大小
在常規(guī)的Android開發(fā)過程中,隨著業(yè)務(wù)邏輯越來越復(fù)雜,調(diào)用棧可能會(huì)越來越深,難免會(huì)遇到調(diào)用棧越界的情況,這種情況下,就需要調(diào)整線程棧的大小。
當(dāng)然,主要還是增大線程棧大小,尤其是存在jni調(diào)用的情況下,C++層的棧開銷有時(shí)候是非常恐怖的,比如說遞歸調(diào)用。
這就需要分三種情況,主線程,自定義線程池,AsyncTask。
主線程的線程棧是沒有辦法進(jìn)行修改的,這個(gè)沒辦法處理。
針對(duì)線程池的情況,需要在創(chuàng)建線程的時(shí)候,調(diào)用構(gòu)造函數(shù)
public Thread(@RecentlyNullable ThreadGroup group, @RecentlyNullable Runnable target, @RecentlyNonNull String name, long stackSize)
通過設(shè)置stackSize參數(shù)來解決問題。
參考代碼如下:
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'); // 工作線程堆棧大小調(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的情況,一般是通過調(diào)用
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params)
指定線程池來運(yùn)行,在特定的線程池中調(diào)整線程棧的大小。
參考代碼如下:
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和線程池以上就是Android如何調(diào)整線程調(diào)用棧大小的詳細(xì)內(nèi)容,更多關(guān)于Android 調(diào)整調(diào)用棧大小的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. Ajax實(shí)現(xiàn)表格中信息不刷新頁面進(jìn)行更新數(shù)據(jù)2. 詳解CSS偽元素的妙用單標(biāo)簽之美3. pip已經(jīng)安裝好第三方庫但pycharm中import時(shí)還是標(biāo)紅的解決方案4. Java Spring WEB應(yīng)用實(shí)例化如何實(shí)現(xiàn)5. UDDI FAQs6. msxml3.dll 錯(cuò)誤 800c0019 系統(tǒng)錯(cuò)誤:-2146697191解決方法7. HTML <!DOCTYPE> 標(biāo)簽8. Python collections模塊的使用方法9. CSS自定義滾動(dòng)條樣式案例詳解10. 將properties文件的配置設(shè)置為整個(gè)Web應(yīng)用的全局變量實(shí)現(xiàn)方法
