2017-04-19 112 views
1

我有一個問題,Realm的關閉實例。我使用ThreadPoolExecutor進行多線程,每個線程使用自己的Realm實例。我在每次操作Realm之前調用Realm.getDefaultInstance()。每當我向Realm提出申訴時,我都會提取舊數據,因爲每次我都會從不同的線程中調用Realm。關閉Realm的所有本地實例

我查看了Realm的來源,看到了Realm的33個本地參考。當我調用Realm.getDefaultInstance()。close(),然後檢查該對象是否關閉時,我得到false。但現在我有32個參考。我如何關閉Realm的所有實例,重置內存緩存並獲取實際數據?

+1

*我在每次操作之前調用Realm.getDefaultInstance()*爲什麼?你應該每個線程只做一次。 *當我調用Realm.getDefaultInstance()。close(),然後檢查該對象是否關閉時,我得到false。*,它不關閉「當前」領域。您應該閱讀文檔以瞭解如何管理領域生命週期 –

+0

因爲使用'Realm.getDefaultInstance()'獲得的每個Realm實例都必須與'realm.close()'配對,請閱讀https:// realm。 io/docs/java/latest /#控制這個realm-instances的生命週期 – EpicPandaForce

+0

好吧,但我檢查一個線程中使用的Realm對象的散列碼,Realm.getDefaultInstance()後面的每個實例都有相同的散列碼。爲什麼Realm在getDefaultInstance()之後返回新的本地實例,而不是當前線程的全局實例? 我需要關閉Realm的每個本地實例? 我可以以某種方式關閉所有本地實例? –

回答

1

我解決了我的問題編輯RealmManager,instaed 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