#android #multithreading
#Android #многопоточность
Вопрос:
У меня есть простой запрос, возвращающий курсор, а затем я провожу курсором и создаю объекты, которые добавляю в ArrayList, вот так:
List<Element> myElements = new ArrayList<Element>();
Cursor c = db.query(...);
c.moveToFirst();
while (c != null amp;amp; !c.isAfterLast()) {
myElements.add(new Element(cursor.getString(0).........)); <-- CREATING THE ELEMENT
c.moveToNext();
}
…
Вы поняли идею.
Проблема в том, что мне нужно запустить 4 подобных запроса, попадающих в разные таблицы и т.д., Но Все они возвращают один и тот же объект Element в конце (после перемещения курсора).
Будучи хорошим гражданином Android, я создал класс, расширяющий AsyncTask, чтобы избежать перегрузки потока пользовательского интерфейса. Кроме того, я хочу выполнить 4 запроса в 4 потоках, чтобы ускорить процесс.
Вопрос:
в моем onPostExecute (курсор c) я запускаю логику, отмеченную как «СОЗДАНИЕ ЭЛЕМЕНТА» выше. Если я запущу 4 потока с 4 запросами и все изменят список, будут ли у меня конфликты потоков, затрагивающие одну и ту же переменную из них? Как мне предотвратить это? Получу ли я что-нибудь от этого, если список, который мне нужно изменить, синхронизирован? Я имею в виду, что потокам все равно придется ждать в очереди, я мог бы также написать 4 запроса и выполнить их последовательно … или нет?
Я понимаю, что хочу исключить это из потока пользовательского интерфейса. Вопрос в том, хочу ли я создать 4 потока (каждый из которых выполняется в AsyncTask) или только ОДНУ AsyncTask, которая последовательно выполняет 4 запроса.
Спасибо!
Llappall
Комментарии:
1. Зачем вам нужно запускать простые запросы к БД асинхронно? Загрузка файлов, которые, как я мог понять, должны обрабатываться отдельно, но я помещаю довольно сложные запросы к БД в поток пользовательского интерфейса, и их возврат занимает всего долю секунды.
Ответ №1:
will I have thread conflicts touching the same variable from them?
У вас, безусловно, будут условия гонки — если вас это устраивает, то никаких проблем.
How do I prevent that? Do I gain anything by threading this if the list I need to modify is synchronized?
Я так не думаю.
I mean, the threads will have to wait in line anyway, I might as well write the 4 queries and run them sequentially... or not?
The question is if I want to create 4 threads (each running in an AsyncTask) or just ONE AsyncTask that runs the 4 queries sequentially.
Я бы выполнил все 4 запроса в одной асинхронной задаче, создание 4 асинхронных задач потребовало бы много работы и поддержки.
Ответ №2:
Vector
в отличие от ArrayList
, синхронизирован и потокобезопасен, поэтому я бы предложил использовать его вместо этого. http://download.oracle.com/javase/6/docs/api/java/util/Vector.html
Другой альтернативой было бы создать новую List
для каждого потока, а затем использовать Collections.addAll()
для включения элементов в исходный список.
Чтобы ответить на вопрос, получите ли вы что-нибудь, запустив несколько потоков, вероятно, ответ будет зависеть от того, насколько дорогостоящими являются выполняемые вами запросы. Запуск нового потока сопряжен с внутренними накладными расходами, поэтому вы хотите убедиться, что запускаемый вами запрос оправдывает затраты.