Android如何调整线程调用栈大小
在常规的Android开发过程中,随着业务逻辑越来越复杂,调用栈可能会越来越深,难免会遇到调用栈越界的情况,这种情况下,就需要调整线程栈的大小。
当然,主要还是增大线程栈大小,尤其是存在jni调用的情况下,C++层的栈开销有时候是非常恐怖的,比如说递归调用。
这就需要分三种情况,主线程,自定义线程池,AsyncTask。
主线程的线程栈是没有办法进行修改的,这个没办法处理。
针对线程池的情况,需要在创建线程的时候,调用构造函数
publicThread(@RecentlyNullableThreadGroupgroup,@RecentlyNullableRunnabletarget,@RecentlyNonNullStringname,longstackSize)
通过设置stackSize参数来解决问题。
参考代码如下:
importandroid.support.annotation.NonNull; importandroid.util.Log; importjava.util.concurrent.ThreadFactory; /** *AThreadFactoryimplementationwhichcreatenewthreadsforthethreadpool. */ publicclassSimpleThreadFactoryimplementsThreadFactory{ privatestaticfinalStringTAG="SimpleThreadFactory"; privatefinalstaticThreadGroupgroup=newThreadGroup("SimpleThreadFactoryGroup"); //工作线程堆栈大小调整为2MB privatefinalstaticintworkerStackSize=2*1024*1024; @Override publicThreadnewThread(@NonNullfinalRunnablerunnable){ finalThreadthread=newThread(group,runnable,"PoolWorkerThread",workerStackSize); //Aexceptionhandleriscreatedtologtheexceptionfromthreads thread.setUncaughtExceptionHandler(newThread.UncaughtExceptionHandler(){ @Override publicvoiduncaughtException(@NonNullThreadthread,@NonNullThrowableex){ Log.e(TAG,thread.getName()+"encounteredanerror:"+ex.getMessage()); } }); returnthread; } }
importandroid.support.annotation.AnyThread; importandroid.support.annotation.NonNull; importandroid.support.annotation.Nullable; importandroid.util.Log; importjava.util.concurrent.BlockingQueue; importjava.util.concurrent.Callable; importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Future; importjava.util.concurrent.LinkedBlockingQueue; importjava.util.concurrent.ThreadPoolExecutor; importjava.util.concurrent.TimeUnit; /** *ASingletonthreadpool */ publicclassThreadPool{ privatestaticfinalStringTAG="ThreadPool"; privatestaticfinalintKEEP_ALIVE_TIME=1; privatestaticvolatileThreadPoolsInstance=null; privatestaticintNUMBER_OF_CORES=Runtime.getRuntime().availableProcessors(); privatefinalExecutorServicemExecutor; privatefinalBlockingQueuemTaskQueue; //Madeconstructorprivatetoavoidtheclassbeinginitiatedfromoutside privateThreadPool(){ //initializeaqueueforthethreadpool.Newtaskswillbeaddedtothisqueue mTaskQueue=newLinkedBlockingQueue<>(); Log.d(TAG,"Availablecores:"+NUMBER_OF_CORES); mExecutor=newThreadPoolExecutor(NUMBER_OF_CORES,NUMBER_OF_CORES*2,KEEP_ALIVE_TIME,TimeUnit.SECONDS,mTaskQueue,newSimpleThreadFactory()); } @NonNull @AnyThread publicstaticThreadPoolgetInstance(){ if(null==sInstance){ synchronized(ThreadPool.class){ if(null==sInstance){ sInstance=newThreadPool(); } } } returnsInstance; } privatebooleanisThreadPoolAlive(){ return(null!=mExecutor)&&!mExecutor.isTerminated()&&!mExecutor.isShutdown(); } @Nullable @AnyThread public Future submitCallable(@NonNullfinalCallable c){ synchronized(this){ if(isThreadPoolAlive()){ returnmExecutor.submit(c); } } returnnull; } @Nullable @AnyThread publicFuture>submitRunnable(@NonNullfinalRunnabler){ synchronized(this){ if(isThreadPoolAlive()){ returnmExecutor.submit(r); } } returnnull; } /*Removealltasksinthequeueandstopallrunningthreads */ @AnyThread publicvoidshutdownNow(){ synchronized(this){ mTaskQueue.clear(); if((!mExecutor.isShutdown())&&(!mExecutor.isTerminated())){ mExecutor.shutdownNow(); } } } }
针对AsyncTask的情况,一般是通过调用
publicfinalAsyncTaskexecuteOnExecutor(Executorexec,Params...params)
指定线程池来运行,在特定的线程池中调整线程栈的大小。
参考代码如下:
importandroid.os.AsyncTask; importandroid.support.annotation.AnyThread; importandroid.support.annotation.NonNull; importandroid.util.Log; importjava.util.concurrent.BlockingQueue; importjava.util.concurrent.ExecutorService; importjava.util.concurrent.LinkedBlockingQueue; importjava.util.concurrent.ThreadPoolExecutor; importjava.util.concurrent.TimeUnit; publicabstractclassAsyncTaskExextendsAsyncTask { privatestaticfinalStringTAG="AsyncTaskEx"; privatestaticfinalintKEEP_ALIVE_TIME=1; privatestaticvolatileThreadPoolsInstance=null; privatestaticintNUMBER_OF_CORES=Runtime.getRuntime().availableProcessors(); privatefinalExecutorServicemExecutor; privatefinalBlockingQueue mTaskQueue; publicAsyncTaskEx(){ //initializeaqueueforthethreadpool.Newtaskswillbeaddedtothisqueue mTaskQueue=newLinkedBlockingQueue<>(); Log.d(TAG,"Availablecores:"+NUMBER_OF_CORES); mExecutor=newThreadPoolExecutor(NUMBER_OF_CORES,NUMBER_OF_CORES*2,KEEP_ALIVE_TIME,TimeUnit.SECONDS,mTaskQueue,newSimpleThreadFactory()); } publicAsyncTask executeAsync(@NonNullfinalParams...params){ returnsuper.executeOnExecutor(mExecutor,params); } /*Removealltasksinthequeueandstopallrunningthreads */ @AnyThread publicvoidshutdownNow(){ synchronized(this){ mTaskQueue.clear(); if((!mExecutor.isShutdown())&&(!mExecutor.isTerminated())){ mExecutor.shutdownNow(); } } } }
参考链接
- IncreaseAsyncTaskstacksize?
- StackOverFlowError:Stacksize1036KBinAsyncTask
- Android:增加调用堆栈大小
- AsyncTask和线程池
以上就是Android如何调整线程调用栈大小的详细内容,更多关于Android调整调用栈大小的资料请关注毛票票其它相关文章!