What is the efficient way to use Realm.getInstance in background threads?


#1

We have an application getting a realm object with Realm.getInstance(ourCfg) before each DB operation an closing it at the end. This solution works fine, but it is very slow due to “validation of all your schemas vs. what is actually on disk” (reference from https://github.com/realm/realm-java/issues/1255). Each getInstance call takes about 50ms!!!

After reading some documentation (https://realm.io/docs/java/latest/#realm-instance-lifecycle) we thought to open a Realm instance per each thread (making several DB operations during his life).
Seems like the following pattern suits very well the purpose:

// Run a non-Looper thread with a Realm instance.
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Realm realm = Realm.getDefaultInstance();
        try {
            // ... Use the Realm instance ...
        } finally {
            realm.close();
        }
    }
});

thread.start();

The problem is that we prefer to not pass the realm object to all inner calls, so we thought to rely on “reference counted cache” and just open a new subsequent instance in the inner calls. It seems like a working solution, but there are 2 questions we would like to ask:

  1. Opening the main Realm instance on the thread start and using it only for the cache purpose, seems like a hack/workaround. Are we really supposed to go this way or we are missing something?
  2. If our threads don’t have a looper, the Realm objects will not be updated periodically. What happens on the close? Is there a merge taking care of aligning the DB?

#2

Realm supports background search natively. Just use Async APIs:

Realm realm = Realm.getDefaultInstance();
mFoo = realm.where(Foo.class).findFirstAsync();
mFoo.addChangeListener(new RealmChangeListener<Foo>() {
   public void onChange(final Foo foo) {
      // this will be called once mFoo got managed and accessor methods are ready to be used. The search performs internally in background thread, not in the one created the query.
   }
})


#3

Thanks for the response, but our goal is to reduce a runtime of getInstance call and not to make the background search…


#4

There is nothing bad to get realm instance from different threads if you are working with change listeners all the time the changes made in realm models will be shared between all threads.

I have not found any better way to work with models across different threads yet.


#5

You are right, but we are talking about getting realm instance several times (opening and closing each time) in the same thread. Such usage slows down the thread, so we thought to open a “main” realm instance to reduce the subsequent getInstance runtime.


#6

What about ThreadLocals? If you are sure the same thread accesses the same realm all the time then you can put the realm into ThreadLocal instance and close it when the thread work is complete.

This would be solution only if multiple threads execute the same code base (method / function).