Reputation: 91
I have a problem, with close instance of Realm. I use ThreadPoolExecutor for multithreading and each thread use own Realm instance. I call Realm.getDefaultInstance() before each opetation with Realm. And every time when I appeal to Realm I fetching old data, because every time I call Realm from different threads.
I looked to sources of Realm and saw 33 local references of Realm. When I call Realm.getDefaultInstance().close() and then check that object is closed I get false. But now I have 32 references. How I can to close all instances of Realm, that reset memory cache and fetch actual data?
Upvotes: 2
Views: 2153
Reputation: 91
I solved my problem writed RealmManager
, instaed Realm.getDefaultInstance()
, I use RealmManager.getInstance()
. More not necessary call realm.close()
after each Realm.getDefaultInstance()
RealmManager:
import android.util.LongSparseArray;
import io.realm.Realm;
public class RealmManager {
private volatile static LongSparseArray<Realm> THREAD_INSTANCES = new LongSparseArray<>();
public static Realm getInstance() {
final long threadId = Thread.currentThread().getId();
if (THREAD_INSTANCES.indexOfKey(threadId) >= 0) {
Realm instance = THREAD_INSTANCES.get(threadId);
if (instance == null || instance.isClosed()) {
instance = Realm.getDefaultInstance();
THREAD_INSTANCES.put(threadId, instance);
}
return instance;
} else {
Realm instance = Realm.getDefaultInstance();
THREAD_INSTANCES.put(threadId, instance);
return instance;
}
}
public static void closeInstance() {
long threadId = Thread.currentThread().getId();
if (THREAD_INSTANCES.indexOfKey(threadId) >= 0) {
Realm instance = THREAD_INSTANCES.get(threadId);
if (instance == null || instance.isClosed()) {
THREAD_INSTANCES.remove(threadId);
} else {
instance.close();
instance = null;
THREAD_INSTANCES.remove(threadId);
}
}
}
}
My JobExecutor:
public class JobExecutor implements Executor {
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private final java.util.concurrent.ExecutorService mThreadPoolExecutor;
private final DiskDataSource mDiskDataSource;
public JobExecutor(DiskDataSource diskDataSource) {
mDiskDataSource = diskDataSource;
mThreadPoolExecutor = Executors.newFixedThreadPool(CORE_POOL_SIZE, new JobThreadFactory());
}
@Override
public void execute(@NonNull Runnable runnable) {
mThreadPoolExecutor.execute(new RealmRunnable(mDiskDataSource, runnable));
}
private static class JobThreadFactory implements ThreadFactory {
private static final String THREAD_NAME = "android_";
private int counter = 0;
@Override
public Thread newThread(@NonNull Runnable runnable) {
return new Thread(runnable, THREAD_NAME + counter++);
}
}
}
RealmRunnable:
public class RealmRunnable implements Runnable {
private Runnable mOrigRunnable;
private DiskDataSource mDiskDataSource;
public RealmRunnable(DiskDataSource diskDataSource, Runnable origRunnable) {
mDiskDataSource = diskDataSource;
mOrigRunnable = origRunnable;
}
@Override
public void run() {
try {
mOrigRunnable.run();
} finally {
mDiskDataSource.closeDatabaseInstance();
}
}
}
Inside DiskDataSource
I use RealmManager
Upvotes: 3