Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Thread Management - Java - Android

I have an application which spawns a new thread when a user asks for an image to be filtered.

This is the only type of task that I have and all are of equal importance.

If I ask for too many concurrent threads (Max I ever want is 9) the thread manager throws a RejectedExecutionException.

At the minute what I do is;

// Manage Concurrent Tasks
private Queue<AsyncTask<Bitmap,Integer,Integer>> tasks = new LinkedList<AsyncTask<Bitmap,Integer,Integer>>();

@Override
public int remainingSize() {
    return tasks.size();
}

@Override
public void addTask(AsyncTask<Bitmap, Integer, Integer> task) {
    try{
        task.execute(currentThumbnail);
        while(!tasks.isEmpty()){
            task = tasks.remove();
            task.execute(currentThumbnail);
        }
    } catch (RejectedExecutionException r){
        Log.i(TAG,"Caught RejectedExecutionException Exception - Adding task to Queue");
        tasks.add(task);
    }
}

Simply add the rejected task to a queue and the next time a thread is started the queue is checked to see if there is a backlog.

The obvious issue with this is that if the final task gets rejected on its first attempt it will never be restarted (Until after it's no longer needed).

Just wondering if there's a simple model I should use for managing this sort of thing. I need tasks to notify the queue when they are done.

like image 741
gav Avatar asked Jun 13 '09 16:06

gav


People also ask

How are threads managed in Android?

When an application is launched in Android, it creates the primary thread of execution, referred to as the “main” thread. Most thread is liable for dispatching events to the acceptable interface widgets also as communicating with components from the Android UI toolkit.

Is Android single threaded?

When an application component starts and the application does not have any other components running, the Android system starts a new Linux process for the application with a single thread of execution. By default, all components of the same application run in the same process and thread (called the "main" thread).

How many thread can I run in Android?

Technically there is no limit, but at some point having more threads is going to be less efficient than having less. If you want to see a pretty much optimal implementation of a ThreadPool look at the source code of the AsyncTask .

What are the two types of thread in Android?

In Android, you can categorize all threading components into two basic categories: Threads that are attached to an activity/fragment: These threads are tied to the lifecycle of the activity/fragment and are terminated as soon as the activity/fragment is destroyed.


2 Answers

The reason for the RejectedExecutionException is because AsyncTask implements a thread pool of its own (per Mr. Martelli's answer), but one that is capped at a maximum of 10 simultaneous tasks. Why they have that limit, I have no idea.

Hence, one possibility is for you to clone AsyncTask, raise the limit (or go unbounded, which is also possible with LinkedBlockingQueue), and use your clone. Then, perhaps, submit the change as a patch to AsyncTask for future Android releases.

Click here to run a Google Code Search for AsyncTask -- the first hit should be the implementation.

If you just want to raise the limit, adjust MAXIMUM_POOL_SIZE to be as big as you're likely to need. If you want to go unbounded, use the zero-argument LinkedBlockingQueue constructor instead of the one being presently used. AFAICT, the rest of the code probably stays the same.

like image 87
CommonsWare Avatar answered Oct 21 '22 10:10

CommonsWare


You seem to have implemented a version of the Thread Pool design pattern -- the wikipedia article points to many helpful articles on the subject, which may help you refine your implementation. I also recommend this Java-specific article which has clear code and explanation.

like image 40
Alex Martelli Avatar answered Oct 21 '22 09:10

Alex Martelli