Имеются ли рекомендации по обеспечению безопасности потоков greenDAO?

Я прохожу с greenDAO, и пока все будет хорошо. Одна вещь, которая, как представляется, не покрывается документами или веб-сайтом (или где угодно:(), - это то, как он справляется с безопасностью потоков.

Я знаю основы, упомянутые в других местах, например, "использовать один сеанс dao" (общая практика для Android + SQLite), и я хорошо понимаю модель памяти Java. Внутренние библиотеки даже кажутся потокобезопасными или, по крайней мере, построены с этим намерением. Но я ничего подобного не видел:

greenDAO кэширует объекты по умолчанию. Это отлично подходит для полностью однопоточной программы - прозрачной и массивной производительности для большинства целей. Но если я, например. loadAll(), а затем изменить один из элементов, я изменяю один и тот же объект по всему миру в своем приложении. Если я использую его в основном потоке (например, для отображения) и обновляя БД на фоновом потоке (как правильно и правильно), существуют очевидные проблемы с потоками, если не будет предпринята особая осторожность.

Обеспечивает ли greenDAO что-либо "под капотом" для защиты от обычных проблем с резьбой на уровне приложений? Например, изменение кэшированного объекта в потоке пользовательского интерфейса при сохранении его в фоновом потоке (лучше надеяться, что они не чередуются, особенно при изменении списка!)? Существуют ли какие-либо "лучшие практики" для защиты от них, помимо общих проблем безопасности потоков (т.е. Чего ожидает GreenDAO и хорошо работает)? Или весь кеш смертельно испорчен с точки зрения безопасности многопоточности?

Ответы

Ответ 1

У меня нет опыта работы с greenDAO, но здесь есть документация: http://greendao-orm.com/documentation/queries/

Говорит:

Если вы используете запросы в нескольких потоках, вы должны вызвать forCurrentThread() в запросе, чтобы получить экземпляр запроса для текущего потока. Начиная с greenDAO 1.3, экземпляры объектов Query привязаны к их собственному потоку, которые строят запрос. Это позволяет безопасно устанавливать параметры объекта Query, в то время как другие потоки не могут вмешиваться. Если другие потоки пытаются установить параметры в запросе или выполнить запрос, привязанный к другому потоку, будет выбрано исключение. Например, вам не требуется синхронизированный оператор. На самом деле вам следует избегать блокировки, поскольку это может привести к взаимоблокировкам, если одновременные транзакции используют один и тот же объект Query.

Чтобы полностью избежать этих потенциальных взаимоблокировок, greenDAO 1.3 ввел метод для CurrentThread(). Это вернет поток-локальный экземпляр запроса, который можно использовать в текущем потоке. Каждый раз, когда вызывается forCurrentThread(), параметры устанавливаются на начальные параметры во время создания запроса с использованием его построителя.

Пока я вижу, что в документации явно не сказано ничего о многопоточности, отличном от этого, кажется довольно ясным, что она обрабатывается. Это говорит о нескольких потоках с использованием одного и того же объекта Query, поэтому ясно, что несколько потоков могут обращаться к одной и той же базе данных. Конечно, для баз данных и DAO нормально работать с одновременным доступом, и в этой ситуации существует множество проверенных методов работы с кэшами.

Ответ 2

По умолчанию GreenDAO кэширует и возвращает экземпляры кэшированных сущностей для повышения производительности. Чтобы предотвратить это поведение, вам необходимо вызвать:

daoSession.clear()

чтобы очистить все кэшированные экземпляры. В качестве альтернативы вы можете позвонить:

objectDao.detachAll()

очистить кешированные экземпляры только для конкретного объекта DAO.

Вам нужно будет вызывать эти методы каждый раз, когда вы хотите очистить кешированные экземпляры, поэтому, если вы хотите отключить все кэширование, я рекомендую называть их в методах доступа к сеансу или DAO.