Search code examples
androidmultithreadingthreadpoolthreadpoolexecutor

Android using multiple threadpoolexecutors


Hey here's an interesting question. I am using in my Android project, lots of sql operations with sqlite. For this matter, I am using thread pool in order of reusing the existing resources. The thread pool look's like this:

final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(NUMBER_OF_CORES*2,NUMBER_OF_CORES*2,1L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(12,true),new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND),new RejectedThread(context));



public class PriorityThreadFactory implements ThreadFactory {

    private final int mThreadPriority;

    public PriorityThreadFactory(int threadPriority) {
        mThreadPriority = threadPriority;
    }

    @Override
    public Thread newThread(final Runnable runnable) {
        Runnable wrapperRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    android.os.Process.setThreadPriority(mThreadPriority);
                } catch (Throwable t) {

                }
                runnable.run();
            }
        };
        return new Thread(wrapperRunnable);
    }

    }




public class RejectedThread implements RejectedExecutionHandler {

    MyLogger myLogger;

    public RejectedThread(Context context) {
        this.myLogger=new MyLogger(RejectedThread.class.getSimpleName(), context);
    }

    @Override
    public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor) {
        this.myLogger.info("Execution rejected for: "+worker.toString());
    }
}

And also I am creating a new Runnable for every CRUD (Create-Read-Update-Delete) operation that I make in the database (being executed by the thread pool above). Here is the questions, beside the threadpool for sql operations, I would need one more thread pool for executing logger operations, to log system behavior for the rest of my functions that I make. Is there a way to prevent any crush/(insufficient resources) because I am using two or more thread pool executors (allocated separated, using in different purposes and never executing a thread pool executor on another thread pool executor) ?


Solution

  • I think that in general your idea is very good, but your implementation is a bit inefficient.

    Try to answer these questions to yourself:

    • Why do you need two thread pools?
    • Do you REALLY need two thread pools?
    • Why do you set CORE size to NUMBER_OF_CORES*2?
    • Why do you set MAX size to NUMBER_OF_CORES*2?
    • Do you REALLY need to overwrite threads priorities?

    In my experience, none of the above complications are really necessary.

    For example, in all my apps I use a single instance of BackgroundThreadPoster class in order to offload work to background threads. The class is very simple:

    /**
     * A single instance of this class should be used whenever we need to post anything to a (random) background thread.
     */
    public class BackgroundThreadPoster {
    
        ExecutorService mExecutorService = Executors.newCachedThreadPool();
    
        public void post(Runnable runnable) {
            mExecutorService.execute(runnable);
        }
    }
    

    Default pre-configured implementation returned by Executors.newCachedThreadPool() works like magic and I've never encountered any need to customize its parameters.

    A full tutorial application that uses this approach can be found here: https://github.com/techyourchance/android_mvc_tutorial

    Maybe this can work for you too?