Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭域的所有本地实例_Java_Android_Multithreading_Realm - Fatal编程技术网

Java 关闭域的所有本地实例

Java 关闭域的所有本地实例,java,android,multithreading,realm,Java,Android,Multithreading,Realm,我有一个问题,与领域的密切实例。我使用ThreadPoolExecutor进行多线程处理,每个线程使用自己的领域实例。我在每次使用Realm操作之前调用Realm.getDefaultInstance()。每次我调用领域时,我都会获取旧数据,因为每次我从不同的线程调用领域时 我查看了Realm的来源,看到了33个Realm的本地引用。当我调用Realm.getDefaultInstance().close()并检查对象是否已关闭时,我得到false。但现在我有32份推荐信。如何关闭Realm的所

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


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

我解决了问题,写了
RealmManager
,安装了
Realm.getDefaultInstance()
,我使用
RealmManager.getInstance()
。在每个
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);
            }
        }
    }
}
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

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