【问题标题】:Close all local instances of Realm关闭 Realm 的所有本地实例
【发布时间】:2017-04-19 08:53:21
【问题描述】:

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

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

【问题讨论】:

  • 每次操作前我都会调用 Realm.getDefaultInstance() 为什么?您可能应该每个线程只执行一次。 当我调用 Realm.getDefaultInstance().close() 然后检查对象是否关闭时,我得到错误。 这不会关闭“当前”领域。您应该真正阅读文档以了解如何管理领域生命周期
  • 因为您使用Realm.getDefaultInstance() 获得的每个Realm 实例都必须与realm.close() 配对,请阅读realm.io/docs/java/latest/…
  • 好的,但是我检查了在一个线程中使用的 Realm 对象的哈希码,在 Realm.getDefaultInstance() 之后获得的每个实例都具有相同的哈希码。为什么 Realm 在 getDefaultInstance() 之后返回新的本地实例而不是当前线程的全局实例?我需要关闭 Realm 的每个本地实例吗?我可以以某种方式关闭所有本地实例吗?
  • 为了方便地允许在onCreate() 中打开领域并在onDestroy() 中为 UI 线程关闭它们,当然。如果您关闭了 any 活动,并且 UI 线程上的每个 Realm 都无效,那将是非常糟糕的,不是吗? :p
  • I need close every local instance of Realm? 这通常很容易,因为每个后台线程应该只有 1 个本地实例,通过 try(Realm realm = Realm.getDefaultInstance()) { ... } 包装线程的生命周期获得,并作为参数传递给方法。

标签: java android multithreading realm


【解决方案1】:

我解决了我写的RealmManager 的问题,我使用Realm.getDefaultInstance(),我使用RealmManager.getInstance()。在每个Realm.getDefaultInstance() 之后没有必要调用realm.close()

领域经理:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2016-09-04
    相关资源
    最近更新 更多