life search. Многопоточность.

Activity Lifecycle, Saving Activity State, Managing Tasks, Intent, Intent Filter
Ответить
Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

life search. Многопоточность.

Сообщение Mykola » 16 янв 2014, 18:48

Всем привет,

Задача: Нужно реализовать живой поиск. Пользователь вводит строку поиска - идет запрос на сервер. Задача проста как 2+2 = ?.

Проблема реализации: С новым добавлением символа стартуем новый поток(AsyncTask). Старый поток отменяем searchTask.cancel(true); вроде все гуд, но... Как управлять потоками?

Много плодиться потоков с состоянием cancel = true.(Парсяться данные, и эту операцию отменить не могу)

Как решаете такую проблему?

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: life search. Многопоточность.

Сообщение Foenix » 16 янв 2014, 21:05

что-то мне подсказывает, что это - плохая идея
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: life search. Многопоточность.

Сообщение anber » 16 янв 2014, 21:11

Mykola писал(а):Задача проста как 2+2 = ?.
:lol:
Много плодиться потоков с состоянием cancel = true.(Парсяться данные, и эту операцию отменить не могу)
Первый же вопрос - какой ответ приходит от сервера? На сколько он большой?
Почему потоков много? По идее достаточно вбить первые 3-5 букв и там будет результат.
Плодится много потоков - чем это не устраивает?
Но это все так, лирическое отступление.

Я бы посмотрел в первую очередь на IntentService (описание есть тут - http://startandroid.ru/ru/uroki/vse-uro ... ka-servisa).
Описание оттуда же:
приложение сыпет в сервис вызовами startService, в которых передает Intent-ы. IntentService принимает эти вызовы в onStartCommand, берет Intent-ы и отправляет их в очередь на обработку. И далее они поочередно обрабатываются в отдельном потоке методом onHandleIntent. Когда последний Intent из очереди обработан, сервис сам завершает свою работу.
Или на ExecutorService, или даже на ThreadPoolExecutor.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 11:09

Первый же вопрос - какой ответ приходит от сервера?
На сколько он большой? лимит 100, но это не важно
Почему потоков много? - "пиво" стартует 4 потока, показать результат нужно только последнего потока.
По идее достаточно вбить первые 3-5 букв и там будет результат. Хм...
Плодится много потоков - чем это не устраивает? Не вопрос, как этим "ведром потоков" управлять и какой размер ведра(пула).
Но это все так, лирическое отступление.

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 11:11

Foenix писал(а):что-то мне подсказывает, что это - плохая идея
Предложите свой вариант, с удовольствием почитаю.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 11:21

Mykola писал(а):Задача проста как 2+2 = ?
дальше даже не читал... со стула упал... real time задачи на сегодня - одни из наиболее сложных в мире.... хоть у вас и не совсем real time, сути это не меняет. Потоками в java управлять нельзя - их можно запустить, убить, посмотреть, что они делают... остальное не гарантированно.
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 11:25

altwin писал(а):
Mykola писал(а):Задача проста как 2+2 = ?
дальше даже не читал... со стула упал... real time задачи на сегодня - одни из наиболее сложных в мире.... хоть у вас и не совсем real time, сути это не меняет. Потоками в java управлять нельзя - их можно запустить, убить, посмотреть, что они делают... остальное не гарантированно.
Я рад, что вам понравилась моя шутка, но для флуда есть отдельная ватка.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 11:29

Mykola писал(а):
Foenix писал(а):что-то мне подсказывает, что это - плохая идея
Предложите свой вариант, с удовольствием почитаю.
https://code.google.com/p/android-query/wiki/AsyncAPI - это можно использовать, как 2+2, Суть в том, что вам нужен AJAX.

P.S. другого пути - Нет, другие библиотеки - есть/можно написать.
Изображение

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 11:43

Mykola писал(а):
Я рад, что вам понравилась моя шутка, но для флуда есть отдельная ватка.
Вы видели live search в Android приложениях от google ? Какой еще ответ вам нужен?

P.S. предложите автодополнение - вариант легко реализуем и работает.
Последний раз редактировалось altwin 17 янв 2014, 14:27, всего редактировалось 1 раз.
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 12:01

altwin писал(а):
Mykola писал(а):
Foenix писал(а):что-то мне подсказывает, что это - плохая идея
Предложите свой вариант, с удовольствием почитаю.
https://code.google.com/p/android-query/wiki/AsyncAPI - это можно использовать, как 2+2, Суть в том, что вам нужен AJAX.

P.S. другого пути - Нет, другие библиотеки - есть/можно написать.
Похожее использую. (AsyncTask+DefaultHttpClient + Gson и пихаю это дело в ThreadPool)
Если делать так, то как убивать потоки в пуле, жалко процессорное время.
Мне интересно как Вы решаете подобную задачу?

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 12:31

Mykola писал(а): Похожее использую. (AsyncTask+DefaultHttpClient + Gson и пихаю это дело в ThreadPool)
Если делать так, то как убивать потоки в пуле, жалко процессорное время.
Мне интересно как Вы решаете подобную задачу?
AsyncTask+DefaultHttpClient + Gson - не похожее, а совсем не то. Суть в том, что AJAX не создает java потоки, а просто выполняет POST. Вы можете создать сколько угодно не блокирующих POST запросов в одном background потоке. Т.е. набирая букву - вы пишите дальше и когда срабатывает callback - выдается результат, который передается в основной поток и там выполняется -отображается.

По сути же - зачем вам создавать много потоков? вы используете editText для поиска,заведите temp и когда пользователь ввел первую букву, поставьте на нее lock(), и никто не будет его трогать до тех пор, пока он не освободится, а как только все ок - обновите temp новыми данными и используйте сразу. Вам не зачем выдавать результат по каждой букве, да и скорость не та, чтобы это было возможно.

P.S тот же google search выдавал ajax результаты вида "asd", "фваоа" и т.д. очень быстро только потому, что они все были в кеше, иначе всегда был запрос. Сейчас же они поняли, что не в этом смысла и предпочитают предложить пользователю варриант автодополнения, что более полезно, чем динамически показывать буквы или их сочетание. Это все реализуемо но не в Android, с его очень ограниченными ресурсами.
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 12:56

Суть в том, что AJAX не создает java потоки, а просто выполняет POST. - не понял.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 13:17

Mykola писал(а):Суть в том, что AJAX не создает java потоки, а просто выполняет POST. - не понял.
ajax - асинхронный JavaScript, обмен json/xml данными между клиентом и сервером. Все, что вам нужно - клиент и сервер умеющие принимать/отдавать json/xml. Все основанно на выполнении http запросов асинхронно, по сути метод выполняющий запрос оставляет callback и умирает. Когда срабатывает callback - это означает, что данные полученны и он может передать их вам. В случае с Android клинт работающий в UI и сервер в background потоках, это просто аналогия к примеру google сервера и браузера пользователя. Вам не нужно реализовывать весь функционал серверов google, а лишь ту часть, которая обрабатывает запросы вашего же клиента. Библиотека, которую я приводил делает что то подобное. Я уже не помню потому, как во всех них принцип не много отличается, но суть одна - ajax. JavaScript запросы достаточно легкие, и живут внутри вашего апа, а вот грузить dalvik кучей java thread ов -ни к чему хорошему не приведет.

P.S. в любом случае это совсем не тривиальная задача. В java вы не можете передать в функцию в качестве callback другую функцию и это основная проблема, хотя можно использовать что то подобное - http://www.javaworld.com/article/207746 ... -java.html, но зачем. AJAX внутри довольно не простая технология и писать релизацию на java врятли того стоит.
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 13:45

Залез я в исходники этой библиотеки а именно AbstractAjaxCallback.java и нашел что и ожидал:

Код: Выделить всё

private static ExecutorService fetchExe;
        public static void execute(Runnable job){
                
                if(fetchExe == null){
                        fetchExe = Executors.newFixedThreadPool(NETWORK_POOL);                        
                }
                
                fetchExe.execute(job);
        }

Код: Выделить всё

 public static int getActiveCount(){
                
                int result = 0;
                
                if(fetchExe instanceof ThreadPoolExecutor){
                        result = ((ThreadPoolExecutor) fetchExe).getActiveCount();
                }
                
                return result;
                
        }
        

Код: Выделить всё

public static void setNetworkLimit(int limit){
                
                NETWORK_POOL = Math.max(1, Math.min(25, limit));
                fetchExe = null;
                
                AQUtility.debug("setting network limit", NETWORK_POOL);
        }

Код: Выделить всё

    private void httpPost(String url, Map<String, Object> params, AjaxStatus status) throws ClientProtocolException, IOException{
                
                AQUtility.debug("post", url);
                
                HttpEntityEnclosingRequestBase req = new HttpPost(url);
                
                httpEntity(url, req, params, status);
            
ajax - подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером. В результате, при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся быстрее и удобнее.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: life search. Многопоточность.

Сообщение anber » 17 янв 2014, 14:00

>>>Первый же вопрос - какой ответ приходит от сервера? На сколько он большой? лимит 100, но это не важно
зачем так много? Тот же гугл показывает 3 варианта. Соответственно скорость заметно выше чем при 100

>>>Почему потоков много? - "пиво" стартует 4 потока, показать результат нужно только последнего потока.
4 потока это не много

>>>Плодится много потоков - чем это не устраивает? Не вопрос, как этим "ведром потоков" управлять и какой размер ведра(пула).
Зависит от логики приложения, сколько пользователь готов ждать, нужны ли все найденные варианты или достаточно парочку.
Собственно для меня непонятен вопрос зачем нужно нужен такой большой лимит - 100.
Пусть показывает 3 варианта, когда пользователь нажмет кнопочку "искать" пусть показывает 100 штук.

Вариант с IntentService и небольшим количеством возвращаемых результатов - один поток, запросы обрабатываются последовательно, по мере поступления, и соответственно отображаются.
К примеру пользователь быстро ввел "пиво": отобразилось сначала для "п", потом с запаздыванием "пи" итд.
Последний раз редактировалось anber 17 янв 2014, 14:06, всего редактировалось 1 раз.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 14:06

повторю, ajax(Asynchronous JavaScript and XML) - это технология асинхронного выполнения JS, не более и не менее. это:
подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером

всего лишь частный случай, хоть и давший популярность + наиболее используемый.

В результате, при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся быстрее и удобнее.

По определению не верно. Страница ВООБЩЕ не перезагружается, т.е. перезагрузка - обработка запроса на повторную загрузку, не смотря на то, что с помощью ajax запроса никто не мешает этого делать, это опять таки результат в частном случае.

Залез я в исходники этой библиотеки а именно AbstractAjaxCallback.java и нашел что и ожидал:

что конкретно? то, что http запросы выполняются в ограниченном пуле потоков? или для вас открытие то, что при превышении лимита запросов создается новый пул? Естественно выполняя побуквенный поиск, т.е. отправку запросов по колличеству соответсвующий числу букв в предложении - вы будете использовать несколько потоков, система просто не даст сделать это в одном. Как и ограничение на число потоков вынуждает ограничивать длину строки поиска.
Какое это имеет отношение вообще к ajax ?
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: life search. Многопоточность.

Сообщение Mykola » 17 янв 2014, 14:15

Ладно хватит холивара. Давайте по существу, сделал так:

Создай пул с размерностью 1 поток (AsyncTask) и запускаю его в этом пуле
xecuteOnExecutor(executor, search);

Перед запуском проверяю:
if (searchTask != null)
{
searchTask.cancel(true);
}

В потоке делаю слип (пользователь вводит текс):
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}

В пуле выполняется один поток, остальные ждут в очереди. Нужный нам поток самый последний в очереди, все остальные перед ним отменены. Такая реализация не очень (проблемное место слип), но всегда выполняется только один поток.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 14:17

Mykola писал(а):

Проблема реализации: С новым добавлением символа стартуем новый поток(AsyncTask).
Много плодиться потоков с состоянием cancel = true.
Вот ключевой момент, это проблема не только в java. Остановить поток гарантированно нельзя, то о чем я писал и было воспринято вами как флуд. Повторю еще раз - ЭТО НЕ ВОЗМОЖНО без использования stop() - который сам по себе опасен шансом убить данные.

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

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: life search. Многопоточность.

Сообщение altwin » 17 янв 2014, 14:22

Mykola писал(а): В пуле выполняется один поток, остальные ждут в очереди. Нужный нам поток самый последний в очереди, все остальные перед ним отменены. Такая реализация не очень (проблемное место слип), но всегда выполняется только один поток.
если после sleep срабатывает interrupt() - то проблемы быть не должно.
Изображение

Ответить