Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225

Многопоточность

29.03.2014, 17:59. Показов 3191. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Тяжелая однако для меня тема многопоточности. Столкнулся вот с такой вот задачей, над которой уже несколько дней "бодаюсь". Помогите пожалуйста разобраться:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ExecutorService executor= Executors.newFixedThreadPool(SIZE_POOL);
        
        for (int i=0; i<favorite.length; i++)
        {   
            Task_Get.favorite=favorite[i];
            Runnable task=new Task_Get();
            //task.run(); 
            executor.execute(task);
            all_favorite.put(favorite[i], Task_Get.address);
            Task_Get.address.clear();
        }
        executor.shutdown();
        try {
            executor.awaitTermination(10, TimeUnit.SECONDS);
            printerFile(all_favorite);
            }
        catch (IOException e) {
            e.printStackTrace();
            } 
        catch (InterruptedException e) {
            System.out.println("Server is overloaded"); 
            e.printStackTrace();
        }
Собственно проблема в том, что процессы по всей видимости спорятся. Так как существует массив favorite а передаются значения как то хаотично, либо вообще выполняется один и тот же, причем то первый то второй(возможно потому что пока что массив всего из 3-х значений). Подскажите что я не так делаю или что нужно изменить, или где нужна синхронизация ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.03.2014, 17:59
Ответы с готовыми решениями:

Многопоточность
Здравствуйте, что-то у меня не выходит ... Должно быть так А . . В А . . В А . . В ... и т.д.

Многопоточность
сделать Дизайн приложения, по крайней мере из двух нитей: - Один для обработки массива - Один для написания результатов в файл.из 2...

Многопоточность
Мне нужно что бы сообщение System.out.println(String.format(&quot;%1$s будит парикмахера.&quot;, client.getName())); выводилось только один раз. В...

24
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
29.03.2014, 18:14
Лучший ответ Сообщение было отмечено turbanoff как решение

Решение

Цитата Сообщение от IGROK@ Посмотреть сообщение
Столкнулся вот с такой вот задачей
Где задача то?

И покажите все необходимые исходники, а не только часть. Что за переменная Task_Get.favorite? Что за all_favorite? Откуда берётся массив favorite?

Добавлено через 1 минуту
PS. Уберите модификатор static у поля Task_Get.favorite для начала.
1
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
29.03.2014, 18:25  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Что за переменная Task_Get.favorite?
это String, который должен постоянно меняться. (в первоначальном виде был констрактор потом сменил концепцию...)
Цитата Сообщение от turbanoff Посмотреть сообщение
Откуда берётся массив favorite?
Он находится в этом же классе, в него изначально я забил список данных, которые в дальнейшем буду формироваться динамически.
Цитата Сообщение от turbanoff Посмотреть сообщение
Уберите модификатор static у поля Task_Get.favorite для начала.
Почему ?

Добавлено через 1 минуту
Цитата Сообщение от turbanoff Посмотреть сообщение
Где задача то?
вот:
Цитата Сообщение от IGROK@ Посмотреть сообщение
процессы по всей видимости спорятся.
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
29.03.2014, 19:04
Цитата Сообщение от IGROK@ Посмотреть сообщение
процессы по всей видимости спорятся.
Что значит "спорятся" ? И почему вы решили что они это делают? (откуда тут процессы, вы же потоки запускаете?)

Нужен как минимум код метода Task_Get.run, чтобы понять что происходит.

Добавлено через 1 минуту
В вашем коде Task_Get.favorite будет иметь значение последнего элемента из массива favorite. Вы уверены что это так нужно?
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
29.03.2014, 19:06  [ТС]
turbanoff, спасибо огромное !!!
Цитата Сообщение от turbanoff Посмотреть сообщение
Уберите модификатор static
в этом и была вся проблема. Сделал поле, поставил Геттер и Сеттер и всё упорядучелось. Тему можно считать закрытой.
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
30.03.2014, 23:21  [ТС]
turbanoff, Не могли бы вы мне помочь с этим же кодом, но немного переработанным ?
Проблема в том, что основной поток MAIN выполняется быстрее чем Task_Get успевает сформировать address и соответственно вылетает ошибка java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Что нужно сделать, что бы можно было убрать Thread.sleep(10000); ? Как я уже писал выше
Цитата Сообщение от IGROK@ Посмотреть сообщение
Тяжелая однако для меня тема многопоточности.
буду очень признателен за помощь
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (int i=0; i<favorite.length; i++)
        {   
            Runnable task=new Task_Get(favorite[i]);
            executor.execute(task);
            try {
                Thread.sleep(10000);
 
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            all_favorite.put(favorite[i], (ArrayList<Character>) Task_Get.address.get(i));
//          Task_Get.address.clear();
        }
        executor.shutdown();
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
31.03.2014, 00:24
Чтобы подождать окончания работы задачи, отправленной в пул можно сделать следующее:
1. Заменить вызов execute на submit. submit вернёт объект типа Future
2. Вызвать метод Future.get. Этот метод блокирует основной поток, пока задача соответствующая объекту Future не будет завершена.
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
31.03.2014, 18:52  [ТС]
turbanoff, спасибо - помогло.
Цитата Сообщение от turbanoff Посмотреть сообщение
Этот метод блокирует основной поток, пока задача соответствующая объекту Future не будет завершена.
Если я все правильно понял, то в такой схеме, многопоточность теряет смысл ? Я бы хотел ускорить работу программы, что бы все созданные потоки работали одновременно (соблюдая очередь при обращении к отдельным методам). И соответственно с имитировать постоянную нагрузку, в виде многочисленных обращений к методу Procces который принимает аргумент favorite и соответственно содержит выше написанный код.
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
31.03.2014, 19:14
IGROK@, Нет, вы же можете сначала для всех тасков вызвать submit, а уже потом, в другом цикле вызывать соответствующие Future.get.
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
31.03.2014, 19:21  [ТС]
turbanoff, но я тогда опять же поймаю
Цитата Сообщение от IGROK@ Посмотреть сообщение
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Добавлено через 2 минуты
Сейчас код имеет вид:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ExecutorService executor= Executors.newFixedThreadPool(SIZE_POOL);
for (int i=0; i<favorite.length; i++)
 {
Runnable task=new Task_Get(favorite[i]);
Future tmp;
            tmp = executor.submit(task);
            try {
                tmp.get();
            } catch (InterruptedException | ExecutionException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
 all_favorite.put(favorite[i], (ArrayList<Character>) Task_Get.address.get(i));
}
 executor.shutdown();
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
31.03.2014, 19:28
IGROK@, Не вызывайте сразу get: положите Future в список, и вызывайте get уже после того как за-submit-или все таски.

Добавлено через 1 минуту
PS. Какого типа у вас Task_Get.address ? Вы точно используете thread-safe типы для обмена данными между потоками?
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
31.03.2014, 20:00  [ТС]
turbanoff, работает! ))Но вылез другой вопрос: Синхронизация... Получается что из 10 переданных параметров favorite[i] выполнились 3 в хаотичном порядке

Добавлено через 3 минуты
но передались все 10 (я в классе Task_Get в методе, который обрабатывает favorite прописал System.out.println(favorite); ) )

Добавлено через 2 минуты
Цитата Сообщение от turbanoff Посмотреть сообщение
Какого типа у вас Task_Get.address ?
ArrayList <ArrayList<Character>> который создается как статик блок при создании объекта типа Task_Get

Добавлено через 1 минуту
Java
1
2
3
4
5
6
public static ArrayList <ArrayList<Character>> favorite;
    
    static {
        favorite= new ArrayList <ArrayList<Character>>();
        
    }
Добавлено через 4 минуты
Цитата Сообщение от turbanoff Посмотреть сообщение
Вы точно используете thread-safe типы для обмена данными между потоками?
не уверен
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
31.03.2014, 20:07
ArrayList не является потоко-безоспасным. Нужно заменить его на какую-нибудь concurrent-коллекцию.
Например на одну из перечисленных здесь - http://habrahabr.ru/company/luxoft/blog/157273/

Добавлено через 6 минут
А еще лучше сделать, чтобы ваши таски просто возвращали значения, а не ложили в глобальную коллекцию. Это избавит от лишних проблем.
1
53 / 53 / 14
Регистрация: 26.02.2014
Сообщений: 150
31.03.2014, 21:25
Игрок, прекратите передавать потокм аргументы через статические переменные, где вы такого набрались?
Выполнение потоков начинается в случайном порядке, не зависящем от того как вы их запускали.
Более того, поток можт начать выполняться раньше, чем ледующая команда в запускающем потоке.
Передавайте аргументы через конструктор, как положено. Или, если хочется извращаться, то через синхронизованную очередь.
1
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
01.04.2014, 08:11  [ТС]
turbanoff, спасибо за всё - разобрался. (не без вашей помощи). На самом деле, была проблема при создании объекта и передачи его параметров в методы класса Task_Get В отношении Future.get. - очень пригодилось.
В целом, я думаю мне еще много нужно тренироваться с потоками, но вроде бы как, стало всё более понятно. Еще раз спасибо.

Добавлено через 2 минуты
Цитата Сообщение от bigwhitefish Посмотреть сообщение
где вы такого набрались?
уже исправился ))
Цитата Сообщение от bigwhitefish Посмотреть сообщение
Передавайте аргументы через конструктор, как положено.
Я понял... )) Спасибо. Из-за этого у меня и было большинство проблем.

Добавлено через 8 часов 39 минут
Не хочу показаться назойливым, но вот что-то мне не нравится код который получился:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  ExecutorService executor= Executors.newFixedThreadPool(SIZE_POOL);
        Future tmp = null;
        for (int i=0; i<favorite.length; i++)
        {   
            Runnable task=new Task_Get(favorite[i], text);
            tmp = executor.submit(task);
            
                        try {
            Thread.sleep(100);              
            } 
                                catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        for (int i=0; i<favorite.length; i++){
            try {
                tmp.get();
                all_favorite.put(favorite[i], (ArrayList<Character>) Task_Get.address.get(i));  
            } 
                               catch (InterruptedException | ExecutionException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    }
        executor.shutdown();
Всё конечно работает, и время работы меня устраивает, но согласитесь - Thread.sleep(100); а затем и объект типа Future.get который должен был избавить от необходимости Thread.sleep ...

Если убрать приостановку трэда в первом цикле, то снова попадаю на то, что Task_Get.address.get(i) не успевает заполнится, не взирая на tmp.get();.
Но в целом, даже с такой задержкой трэдов, программа успевает (порядка за 2 секунды) - сформировать 10 массивов, (размер боюсь даже предположить, так как вычитываются данные из файла в виде чаров - порядка 10 тыс. символов в одном файле(длину массива не проверял)) положить в HashMap, а затем создать 10 новых файлов и перезаписать в них ранее полученные 10 массивов. И еще одно, файлы находятся на удаленном сервере (на сайте)
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.04.2014, 08:41
Я же просил Future в список положить, а вы запоминаете и вызываете get только у последнего Future.
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
01.04.2014, 08:48  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Future в список положить
Но как ? ведь у Future.get нет индексов. Как я могу создать с него список ?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
01.04.2014, 08:54
Лучший ответ Сообщение было отмечено IGROK@ как решение

Решение


Java
1
2
3
4
5
6
7
8
9
10
11
12
        List<Future> futures = new ArrayList<Future>();
        for (int i=0; i<favorite.length; i++) {   
            Runnable task=new Task_Get(favorite[i], text);
            Future future = executor.submit(task);
            futures.add(future);
        }
        for (Future future : futures ) {   
            future.get();
        }
        for (int i=0; i<favorite.length; i++) {   
            all_favorite.put(favorite[i], (ArrayList<Character>) Task_Get.address.get(i)); 
        }
1
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
01.04.2014, 09:18  [ТС]
turbanoff, спасибо - я бы не додумался...

Добавлено через 5 минут
turbanoff, я когда доработаю весь код программы, хочу развернуть проект в интернете (jsp + servlet) на вашу поддержку можно будет рассчитывать ? а то я не когда не разворачивал проект. Может что небуть посоветуете, какой-то мэнуал ?
0
1 / 1 / 1
Регистрация: 05.04.2013
Сообщений: 225
02.04.2014, 17:16  [ТС]
Вопрос: А как на счет 10 тысяч потоков ??? будет работать ? есть ли какое то ограничение количества потоков ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.04.2014, 17:16
Помогаю со студенческими работами здесь

Многопоточность
Добрый день, уважаемые гуру многопоточного программирование. Если Вас не затруднит, ответьте пожалуйста на несколько вопросов: 1 К...

Многопоточность
Данный код должен в теории выдавать произвольное число (в определенном интервале). У меня четко каждый раз 200 000. В чем ошибка? ...

Многопоточность
Люди, не могли бы вы на пальцах объяснить, что такое пул потоков, а то перечитал тучу статей, а все равно не совсем представляю себе что...

Многопоточность
Доброго времени. Не могу сообразить как сделать: Задача: Методы класса Main вызываются из разных потоков. Нужно получить статистику...

Многопоточность NullPointerException
Кто-нибудь может подсказать, почему при k=2 и z=1 выбрасывается ошибка NullPointerException и как побороть данную проблему? class...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru