HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Iterate faster through the Android file system and find specific files using java multithreading

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
findthefileandroidsystemjavaiteratefasterfilesusing

Problem

I'm trying to extract specific files and visualise them in a list/grid. For that purpose I'm starting a Service to do the background job, and when it finishes it fires an Intent which will be captured by a Fragment/Activity. The files are extracted in an singletone container which feeds the adapter when the broadcast is received.

I want to do this in the fastest way possible, so I'm using many threads.

The service:

```
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;

import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class ExtractFilesService extends Service {

public static String FILE_SCAN_COMPLETE = "ExtractFilesService#FILE_SCAN_COMPLETE";

private CopyOnWriteArrayList extractedFilesList;

private ExecutorService threadPool;

private AtomicInteger threadCounter = new AtomicInteger(0);

private FileFilter mFilenameFilter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory()
|| pathname.getName().endsWith(".pdf")
|| pathname.getName().endsWith(".epub");
}
};

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

extractedFilesList = new CopyOnWriteArrayList<>();

// What is the optimal pool size ?
// It should differ on various devices, so
// how to adjust the value based on the device?
// Are there any other best practices for executing unknown number of threads simultaneously?
threadPool = Executors.newFixedThreadPool(10);

// getting t

Solution

Have you read the docs of CopyOnWriteArrayList?


As the name suggest CopyOnWriteArrayList creates copy of underlying ArrayList with every mutation operation e.g. add or set. Normally CopyOnWriteArrayList is very expensive because it involves costly Array copy with every write operation but its very efficient if you have a List where Iteration outnumber mutation e.g. you mostly need to iterate the ArrayList and don't modify it too often.

That's really not a good fit for your use case.
How about a ConcurrentLinkedQueue instead?

As for optimal number of threads, logically it's hard to do better than the number of CPU cores. If I remember correctly the recommended count is usually the number of cores + 1. I don't know specifically for Android, but I think the same logic should hold true. See also this related post: https://stackoverflow.com/a/13958877/641955

Context

StackExchange Code Review Q#105684, answer score: 5

Revisions (0)

No revisions yet.