![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
ROKR |
|
||||||||||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Имеется задание:
"Выполнить приложение командной строки с двумя параметрами , один из которых – количество потоков, другой параметр – количество выводимых строк Нужно так синхронизовать потоки, чтобы имена потоков выводились поочередно- в каскадном порядке. Под синхронизацией подразумевается использование конструкции synchronized и методов wait, notify. Использование флагов для выполнения синхронизации не допускается. (имя1 имя 2 имя 3 имя 4 имя 5 …. имя 1 имя 2 имя 3 имя 4 имя 5 …. .......)" Привожу код, который написал:
Кол-во потоков и кол-во строк передается в args[]. Создается экземпляр класса B, который потом передается в качестве параметра в класс A, реализующий потоки. В классе B метод print синхронизируется. Потоки запускаются через 10 мсек. Опишу метод paint():
Когда поток приходит в метод, выводится его номер, затем поток вызывает wait(). count нужно для перевода строки. max - кол-во потоков. с и strings текущая строка потока и требуемое для вывода кол-во строк соответственно. Вот тут начинается расхождение. Моя идея лежит в следующем: Когда приходит последний поток, он, перед wait`ом вызывает notify(), таким образом пробуждая первый поток, вызвавший wait(). Затем, пока count_a != 0, вызывается notify(), пробуждая потоки в том порядке, в котором они пришли в метод paint() и вызывали wait(). Следуя документации, такого быть не должно:
notify() Однако, вывод оказывается следующим:
Тестировал код при разных кол-вах потоков (от 100 до 2000) и строк(10 1000). Тестировал на разных компьютерах. Результат один. Преподаватель говорит, что код не правильный, и что если 1000 раз выводилось верно, то на 1001 результат будет не верный. Почему тогда при выводе нет разброса потоков? ----------------------------------------------------------------- Скачал Шилдта - Java 2 The Complete Reference. Там написано следующее:
стр. 297 |
||||||||||
|
|||||||||||
revenforv |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
А собственно какой вывод требуется на выходе, контрольный пример, пожалуйста.
![]() |
|||
|
||||
ROKR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
В самом начале пример:
Но, судя по документации и коду, вывод должен быть другим, например: имя 1 имя 5 имя 3 имя 4 имя 2 …. Этого же мнения придерживается и преподаватель. Это сообщение отредактировал(а) ROKR - 26.9.2009, 17:19 |
|||
|
||||
revenforv |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
Вообще-то нет.. в документации написано
Т.е. алгоритм выбора определяется реализацией. Насколько я помню, поскольку у всех создаваемых вами потоков приоритет одинаковый, то выбирается первый из очереди. Если не вру, то в стандартной реализации должна использоваться очередь с приоритетами.. В общем как-то так (давно я этим не занимался - могу и соврать). |
|||
|
||||
revenforv |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
Посмотрю как можно решить задачу - через полчасика напишу, что получилось.
|
|||
|
||||
ROKR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Вот, и я думаю также, но!, преподаватель уперлась в слово "arbitrary". И хоть бы что =). Или найти в книге Шилдта упоминание про очередь.
|
|||
|
||||
revenforv |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
В общем задача прочитать то что я написал и понять идею:
Добавлено @ 19:37 Сравнить с той же программой, но в которой метод print() заменен на:
Это сообщение отредактировал(а) revenforv - 26.9.2009, 19:56 |
||||
|
|||||
revenforv |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
Тест 1 (для первоначального варианта программы - с очередью синхронизации)
Тест 2
|
||||
|
|||||
ROKR |
|
||||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Вот что нашел в книге Core Java2 Volume 2 Advenced Features:
А в Шилдте вот что:
Т.е., как я понял все работа с потоками ложится на ОС, а не на JVM. |
||||
|
|||||
revenforv |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
А теперь пару слов о неявных очередях и синхронизации потоков:
1. Приоритет потоков не влияет на порядок выборки потоков из locking set (в Sun JVM). 2. Текущая реализация Sun JVM поддерживает неявную реализацию locking set в виде очереди синхронизации. Однако, эту особенность нельзя учитывать при написании реальных программ, т.к. в будущем все может измениться.
3. В описанной выше программе после прохода первой строки всегда остается активным только один поток, который и освобождает только один поток. И это первый поток, который ждет в очереди.
Добавлено @ 20:27 Не совсем так.. я для того и привел два примера метода print(). Первый полагается на синхронизационное множество, за которым следит JVM (и определяет его реализацию). А второй - синхронизуется средствами ОС. Т.е. в действительности только ОС обеспечивает arbitrary выборку потоков (которые, к слову блокированы ею же - к синхронизации Java это не имеет отношения, JVM только гарантирует, что два потока не будут одновременно выполнять synchronised метод). Это сообщение отредактировал(а) revenforv - 26.9.2009, 20:28 |
||||
|
|||||
ROKR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Где про этот факт можно узнать? |
|||
|
||||
revenforv |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
Продемонстрируйте на примере вот этой программки, которая для N потоков сначала печатает их номера с префиксом F и блокирует их, а потом (после разблокирования) печатает с префиксом S.
Все потоки поочередно с перерывом в 500 мск разблокируются еще одним потоком. Обратить внимание на то, что: 1. Порядок печати номеров совпадает 2. Сначала печатаются все F, а потом все S
Для сравнения запустить программу 2, в которой N+1 поток использует метод unlockAll() потоки будут напечатаны в произвольном порядке (разблокирование начинается через N*500 мск, чтобы печати с F не перемешивались с выводами S).
PS. Кстати, можно заметить, что потоки по notifyAll вываливаются в обратном порядке т.е. реально Sun JVM использует в качестве арбитрарного алгоритма FIFO для notify() и LIFO для notifyAll(). Но, опять же, это недокументированная особенность реализации и про нее вам никто не скажет - она доказывается чисто эмпирически. В качестве доказательства можете использовать Duck Test. Это сообщение отредактировал(а) revenforv - 27.9.2009, 18:22 |
||||
|
|||||
ROKR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: нет Всего: 1 |
Спасибо за помощь!
![]() Поговорю еще с преподователем, но на всякий случай сделал еще двумя способами задачу: с помощью управляющего потока, и когда каждый поток пробуждает следующий. Это сообщение отредактировал(а) ROKR - 28.9.2009, 00:10 |
|||
|
||||
revenforv |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 6.8.2009 Где: Санкт-Петербург Репутация: нет Всего: нет |
Вообще-то в документации написано четко:
Это и означает, что выбор произвольный и происходит по усмотрению реализации. Последовательный выбор - это тоже произвольный на усмотрение реализации. Так что в документации нет никакого противоречия, там ведь не сказано ничего типа randomly. |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |