关闭领域的所有本地实例

时间:2017-04-19 08:53:22

标签: java android multithreading realm

我有一个问题,有一个关闭Realm的实例。我使用ThreadPoolExecutor进行多线程处理,每个线程都使用自己的Realm实例。我在每次与Realm的操作之前调用Realm.getDefaultInstance()。每当我向Realm提出申诉时,我都会获取旧数据,因为每次我从不同的线程调用Realm。

我查看了Realm的来源,看到了33个Realm的本地引用。当我调用Realm.getDefaultInstance()。close()然后检查该对象是否已关闭时,我得到了错误。但现在我有32个参考。如何关闭Realm的所有实例,重置内存缓存并获取实际数据?

1 个答案:

答案 0 :(得分:2)

我解决了我的问题,写了RealmManager,安装了Realm.getDefaultInstance(),我使用了RealmManager.getInstance()。更多不必在每个realm.close()

之后致电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);
            }
        }
    }
}

我的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();
        }
    }
}

DiskDataSource内,我使用RealmManager