有没有关于greenDAO线程安全的最佳实践?

19

我正在使用greenDAO,目前进展顺利。然而,文档或网站(或任何地方 :( )似乎都没有涉及它如何处理线程安全的问题。

我知道其他地方提到的基本原则,例如“使用单个 DAO 会话”(Android + SQLite 的一般实践),并且我非常了解 Java 内存模型。该库内部甚至看起来是线程安全的,或者至少是有这个意图构建的。但是我没有看到任何东西涵盖以下问题:

默认情况下,greenDAO 会缓存实体。 这对于完全单线程的程序来说非常好 - 对于大多数用途来说,这是透明的,并且可以显著提高性能。但是,如果我例如loadAll() 然后修改其中一个元素,我将在整个应用程序中 全局 修改同一个对象。如果我在主线程上使用它(例如进行显示),并在后台线程上更新数据库(正常操作),除非采取额外的注意措施,否则会出现明显的线程问题。

greenDAO 是否在“幕后”做些什么以防范常见的应用程序级别的线程问题?例如,在 UI 线程中修改缓存的实体,同时在后台线程中保存它们(最好希望它们不会交错!特别是在修改列表时!)?是否有任何“最佳实践”可以防止这些问题,超出一般的线程安全考虑范围(即,greenDAO 预期并很好地处理的内容)?或者整个缓存从多线程应用程序的安全性角度来看存在致命缺陷?

2个回答

2
我没有使用过greenDAO,但是这里的文档: http://greendao-orm.com/documentation/queries/ 说:
如果您在多个线程中使用查询,则必须在查询上调用forCurrentThread()以获取当前线程的Query实例。从greenDAO 1.3开始,Query对象的对象实例绑定到构建查询的所属线程。这使您可以安全地在Query对象上设置参数,而其他线程不能干扰。如果其他线程尝试在查询上设置参数或执行绑定到另一个线程的查询,则会抛出异常。因此,您不需要同步语句。实际上,应避免锁定,因为如果并发事务使用相同的Query对象,则可能导致死锁。 为了完全避免这些潜在的死锁,greenDAO 1.3引入了方法forCurrentThread()。这将返回Query的本地线程实例,可在当前线程中安全使用。每次调用forCurrentThread()时,参数都设置为使用其构建器构建查询时的初始参数。
虽然就我所见,文档并没有明确说明关于多线程的内容,除此之外,它似乎非常清楚地处理了多线程。这是在谈论多个线程使用相同的Query对象,因此显然多个线程可以访问同一个数据库。当然,对于数据库和DAO处理并发访问是很正常的,并且在这种情况下有许多经过验证的缓存处理技术。

0

默认情况下,GreenDAO会缓存实体并返回缓存实例以提高性能。如果要防止此行为,需要调用:

daoSession.clear()

清除所有缓存实例。或者您可以调用:

objectDao.detachAll()

只清除特定DAO对象的缓存实例。

每次想要清除缓存实例时,您需要调用这些方法,因此如果要禁用所有缓存,请建议在Session或DAO存取器方法中调用它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接