user68621 user68621 - 14 days ago 5
Android Question

ExecutorService one threaded threadpool is blocking the queue if too many requests are executed

I am using a threadpool with only one thread to execute some network tasks (They need to be executed sequentially)through a viewholder in a RecyclerView in Android.
It is working, if I am scrolling slow. But if I am scrolling fast, too many tasks will be pushed to the queue, which I have discovered through debugging, is blocking the queue entirely.

I have simplified the code (much) where I am using the one threaded threadpool:

if (executorService == null) {
executorService = Executors.newFixedThreadPool(1);
}

executorService.execute(new Runnable() {
@Override
public void run() {
RessourceService.getCoverPage(url, callback);
while (waiting) {}
}
});


So what is the alternatives, if I want to execute network tasks sequentially without getting a blocked queue??

Any help will be greatly appreciated.

Update:
The problem was somewhere else in my code and not in that posted above. As described in my question, I am executing the requests through a viewholder of a recyclerview. When scrolling fast, the images are not loaded. I found out that the problem was occurring when an item was out of sight in the recyclerview. The reason for this, was that the request was locked due to my "waiting" variable being true. I could solve it by making it static and setting it to false right before each request and thereby stopping the request in progress in another viewholder.
Nevertheless, the suggesting by @Jessie Brian Revil on using newSingleThreadExecutor, makes perfectly sense. Not a direct solution to my problem, but a reasonable solution for the code above (Therefore accept).

Answer

Have you tried using newSingleThreadExecutor()

public static ExecutorService newSingleThreadExecutor()

Creates an Executor that uses a single worker thread operating off an unbounded queue.

(Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)

Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.