Android запрашивает изменение переменной в потоке пользовательского интерфейса

#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() для включения элементов в исходный список.

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