Может кто-нибудь пояснить один момент. В последней задаче, где создаются 3 нити и один объект. Метод run(), который реализует Water один для каждой нити и они просто вызывают его поочередно (попользовался сначала один поток, потом другой и т.д.) или этот метод дублируется для каждого потока и они(потоки) ждут своего времени и отрабатывают каждый свой run()?
Максим
40 уровень
Дублируется ли метод run()?
Обсуждается
Комментарии (7)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Ярослав Java Developer Master
27 апреля 2018, 06:26
Для таких вопросов нужно код прикладывать, чтобы было ясно, о чем речь. Ведь ты даже не указал, что значит "другие нити" - классы, производные от класса Water, в свою очередь Water производный от Thread, или как именно? Чтобы таких уточняющих вопросов не возникало, просто прикладывай код и всё.
0
Максим
27 апреля 2018, 07:56
Я подумал, что это не столь важно, т.к. по сути даже не важно какая задача. Просто если есть 3 потока и один объект. Все потоки работают с этим одним объектом. Метод run() один для всех потоков или для каждого потока он свой ?
+1
Ярослав Java Developer Master
27 апреля 2018, 08:24
Статические поля общие для всех экземпляров класса, нестатические - у каждого экземпляра свой. Это достаточный ответ? run у каждого экземпляра класса Water свой, просто выполняет одни и те же действия.
Если же ты имеешь, что происходит после вызова метода run у множества нитей, то они начинают переключаться друг на друга в случайном порядке после каждого кванта времени.
Если есть 5 нитей, которые работают, то управление будет передаваться случайным образом за небольшие промежутки времени каждой нити. Например: сначала 2, отработала какие-то миллисекунды, передалось время 4-й нити, 4 передала 3, 3 снова 4, 4 передала 1, и так до завершения всех нитей.
Но, по формулировке вопроса, ты, наверное, имеешь ввиду, если есть 4 нити, будут ли они выполнять один run вместе. Типа, первая нить выполнила 38 строчку метода, вторая нить выполнила 39 и так далее. Так не работает. Даже если бы метод был статическим, это бы не работало.
0
Максим
27 апреля 2018, 08:39
Нет, немного не то. Смотри, есть 1 экземпляр и несколько нитей. У экземпляра есть метод run(), а вот для нитей этот метод дублируется? run() в Water ведь переопределяет run() из класса родителя Thread. Как эти три потока видят этот переопределенный run() ? Для всех потоков один и тот же переопределенный run() или каждая нить видит как бы свой метод? (Понятно, что один поток выполняет run() полностью сам не совместно с другими потоками)
0
Ярослав Java Developer Master
27 апреля 2018, 13:06
Water не переопределяет метод run из Thread, он его реализует из-за интерфейса Runnable. И я понял, что ты имеешь ввиду (вроде бы). Скорее всего, это какие-то внутренние особенности класса Thread, у каждой же нити есть свой статус (выполняется, выполнилась, ждет и так далее), и, скорее всего, просто когда нить из созданной переходит в "выполняется", она вызывает метод run объекта. Так как в run объект никак не изменяется и у каждого объекта свое собственное свойство commonResource, то все нормально, а в идеале для каждой нити должен создаваться свой объект. Например, если бы у нас была нить с ссылкой на таймер, который бы имел переменную boolean isStopped, а в run был бесконечный цикл, пока !isStopped, и первая нить изменила таймер, то все остальные созданные нити прервались бы тоже, так как объект изменил бы свое состояние, и в каждой ните метод run бы завершился.
run - это просто метод. Нестатический метод. Он вызывается тогда, когда ните это нужно. У каждой нити есть свой статус, когда нить переходит первый раз в статус "выполняется", она вызывает этот метод у объекта. Если даже все нити указывают на один объект, каждая будет вызывать run отдельно. Никакой магии тут нет.
И про "как потоки видят переопределенный метод и видят ли нити каждый якобы свой метод" - полная чушь, которая только показывает, что ты недостаточно хорошо осознал ООП. Вот пример: есть объект Cat cat = new Cat();, cat обладает нестатическим методом meow(), который выводит фразу "Мяу" в консоль. И есть три метода: makeCatSayHelloOneTime, makeCatSayHelloTwoTimes, makeCatSayHelloTenTimes.
В первом методе вызывается cat.meow() один раз, во втором два раза, и в третьем десять раз. Но независимо от того, из какой точки программы был вызван метод, мы всегда будем вызывать метод именно объекта cat, и так же с нитями. Если ты передал один и тот же объект, то каждая нить просто будет вызывать один и тот же метод, просто у каждой нити будет свое состояние и каждая будет уникальна. Вот и весь секрет.
+3
Максим
28 апреля 2018, 11:30
Спасибо, именно такой ответ и ждал. Насчет "переопределения run()", да, неправильно выразился. Про meow(), да это понятно.
0
РоманExpert
1 мая 2018, 17:31
Мы имеем ссылку water (находится в стэке)
на объект типа Water (находится в куче)
создаются 3 новых объекта класса Thread (находятся в куче)
ссылки на них тоже есть, хотя они неявны.
Т.о. у нас есть:
- 3 объекта класса Thread
- один объект класса Water
- одна ссылка water на объект типа Water
Чтобы запустить поток/нить на выполнение, классу Thread нужно передать объект типа Runnuble, которым и является объект Water, имплементирующий Runnable. Поэтому метод интерфейса run() переопределяется в классе Water.
Точкой входа для нового потока служит метод run() (как у основного потока программы метод main() ).
Поэтому, когда пишется
это означает, что JVM (в основном потоке main) запускает у созданного потока (объекта Thread) метод start(), который запускает метод run() объекта Water. Т.о. новый поток будет выполнять команды метода run() объекта Water параллельно с основным потоком программы (main).
Каждый раз (в данном случае 3 раза в цикле), новому объекту типа Thread в качестве Runnuble передается ссылка на один и тот же объект Water,
т.е. все три потока содержат в себе ссылку (water) на один и тот же объект Runnable (Water)
и они (потоки/нити) запускают один и тот же метод run() у объекта Water через ссылку water.
Задача показывает, что можно изменять одновременно один и тот же объект тремя разными нитями.
Это как 3 дровосека (Thread) рубят один пень (Water) одновременно (но по-очереди).
Кто ударит первым и сколько раз - выбирается операционной системой и не зависит от создателя программы, если приоритеты у всех дровосеков (потоков/нитей) одинаковы
+7