Здравствуйте, Hard_Club, Вы писали:
H_C>Кто-нибудь знает истинную причину почему разработчики языка не ввели отдельный объкт монитор, а объеденили его с Object? H_C>http://javarevisited.blogspot.sg/2012/02/why-wait-notify-and-notifyall-is.html
IMHO, дизайнерам языка в начале 90х это казалось модно и современно. Потому что многопоточность уже появилась. Но что с ней делать, толком ещё никто не знал.
Здравствуйте, Blazkowicz, Вы писали:
B>IMHO, дизайнерам языка в начале 90х это казалось модно и современно. Потому что многопоточность уже появилась. Но что с ней делать, толком ещё никто не знал.
А почему тогда в .Net тоже мониторы на объектах?
Здравствуйте, Hard_Club, Вы писали:
H_C>Кто-нибудь знает истинную причину почему разработчики языка не ввели отдельный объкт монитор, а объеденили его с Object? H_C>http://javarevisited.blogspot.sg/2012/02/why-wait-notify-and-notifyall-is.html
Ответ очень прост и прозаичен — потому что это удобно с точки зрения прикладного разработчика. Не больши и не меньше. Хотите разнести эти два понятия — не вопрос, используйте Lock.
Здравствуйте, devcoach, Вы писали:
D>А почему тогда в .Net тоже мониторы на объектах?
Ответ лежит на поверхности. Потому что .Net подчистую слизали с Java.
Здравствуйте, devcoach, Вы писали:
D>Ответ очень прост и прозаичен — потому что это удобно с точки зрения прикладного разработчика. Не больши и не меньше. Хотите разнести эти два понятия — не вопрос, используйте Lock. http://c2.com/cgi/wiki?EveryObjectIsaMonitor
Да, как для 1995го года, казалось, довольно удобно. А в итоге вышло, что никак не защищает разработчика от ряда косяков, да ещё и не расширяется никак.
ReentrantLock и synchronized работают по-разному и дают разную производительность в зависимости от нагрузки. Lock не имеет bias locking оптимизации. Но при этом под нагрузкой показывает бОльшую эффективность, чем synchronized.
Здравствуйте, Blazkowicz, Вы писали:
B>Ответ лежит на поверхности. Потому что .Net подчистую слизали с Java.
Подчистую, да не подчистую. Дженерики другие, value types — они не тупо передирали, а стремились избавиться от недостатков Java. Поэтому, если бы они видели в этом необходимость, они бы их переделали. Но смысла переделывать удобный инструмент не было.
Здравствуйте, Blazkowicz, Вы писали:
B>http://c2.com/cgi/wiki?EveryObjectIsaMonitor B>Да, как для 1995го года, казалось, довольно удобно. А в итоге вышло, что никак не защищает разработчика от ряда косяков, да ещё и не расширяется никак. B>ReentrantLock и synchronized работают по-разному и дают разную производительность в зависимости от нагрузки. Lock не имеет bias locking оптимизации. Но при этом под нагрузкой показывает бОльшую эффективность, чем synchronized.
От каких косяков?
Здравствуйте, devcoach, Вы писали:
D>Подчистую, да не подчистую. Дженерики другие, value types — они не тупо передирали, а стремились избавиться от недостатков Java.
Генерики добавили во второй версии, когда .Net уже стал достаточно популярен.
Структуры, как им многое другое, остались как наследие C++.
Никто же не спорит что в .Net пытались что-то улучшить. Что могли, то улучшили. До многопоточности дело не дошло, потому что в начале 2000х, когда .NET слизывлся с Java особой надобности заниматься многопоточностью не было. Хватало базовых примитивов.
D>Поэтому, если бы они видели в этом необходимость, они бы их переделали. Но смысла переделывать удобный инструмент не было.
Это вообще не аргумент. Если .Net не стал чего-то переделывать копируя Java, это ещё не значит, что оно реализовано идеально.
Здравствуйте, devcoach, Вы писали:
D>От каких косяков?
Возможность синхронизироваться на чем попало, не задумываясь о последствиях. Например не final полях или публично доступных объектах.
Истинная причина — стремление к упрощениею, хотя лично мне кажется, что это была ошибка.
С практической точки зрения плата за нее — лишнее поле lock monitor в каждом объекте (4 байта на 32-разрядной JVM). Это справедливо для Open JDK / Oracle Java / Android Java. С логической IMO это тоже не имеет смысла для ряда классов.
Уж лучше бы дизайнеры языка ввели интерфейс-маркер Lockable, который нужно было бы реализовывать если бы нужно было использовать synchronized методы. JRE встречая Lockable добавлял соответствующее поле в представление объекта.
Здравствуйте, A13x, Вы писали:
A>Истинная причина — стремление к упрощениею, хотя лично мне кажется, что это была ошибка. A>С практической точки зрения плата за нее — лишнее поле lock monitor в каждом объекте (4 байта на 32-разрядной JVM). Это справедливо для Open JDK / Oracle Java / Android Java. С логической IMO это тоже не имеет смысла для ряда классов.
Поля "lock monitor" в объекте нет. Есть заголовок объекта, который используется под различные нужды JVM, в том числе и под хранение информации о мониторе.
Здравствуйте, Blazkowicz, Вы писали:
B>Возможность синхронизироваться на чем попало, не задумываясь о последствиях. Например не final полях или публично доступных объектах.
Ну на не-final поляк синхронизироваться то как раз абсолютно нормально. А вот возможность синхронизации на некоторых классах java.* может сбить с толку некоторых новичков в многопоточности, да.
Здравствуйте, devcoach, Вы писали:
D>Здравствуйте, Blazkowicz, Вы писали:
B>>http://c2.com/cgi/wiki?EveryObjectIsaMonitor B>>Да, как для 1995го года, казалось, довольно удобно. А в итоге вышло, что никак не защищает разработчика от ряда косяков, да ещё и не расширяется никак. B>>ReentrantLock и synchronized работают по-разному и дают разную производительность в зависимости от нагрузки. Lock не имеет bias locking оптимизации. Но при этом под нагрузкой показывает бОльшую эффективность, чем synchronized. D>От каких косяков?
Лок могут захватить кто угодно, так как доступ к объкту класса публичный. И надо следить везде где объект используется, то есть по всему приложению, правильно ли его синхронизируют и не будет ли deadlock. А если объявить просто приватный объект и использовать его для монитора, то все видно в одном классе.
Здравствуйте, devcoach, Вы писали:
D>Здравствуйте, A13x, Вы писали:
A>>Истинная причина — стремление к упрощениею, хотя лично мне кажется, что это была ошибка. A>>С практической точки зрения плата за нее — лишнее поле lock monitor в каждом объекте (4 байта на 32-разрядной JVM). Это справедливо для Open JDK / Oracle Java / Android Java. С логической IMO это тоже не имеет смысла для ряда классов. D>Поля "lock monitor" в объекте нет. Есть заголовок объекта, который используется под различные нужды JVM, в том числе и под хранение информации о мониторе.
/*
* There are three types of objects:
* Class objects - an instance of java.lang.Class
* Array objects - an object created with a "new array" instruction
* Data objects - an object that is neither of the above
*
* We also define String objects. At present they're equivalent to
* DataObject, but that may change. (Either way, they make some of the
* code more obvious.)
*
* All objects have an Object header followed by type-specific data.
*/struct Object {
/* ptr to class object */
ClassObject* clazz;
/*
* A word containing either a "thin" lock or a "fat" monitor. See
* the comments in Sync.c for a description of its layout.
*/
u4 lock;
};
Ключевые места: > All objects have an Object header followed by type-specific data. > A word containing either a "thin" lock or a "fat" monitor.
Здравствуйте, A13x, Вы писали:
A>https://github.com/android/platform_dalvik/blob/master/vm/oo/Object.h
А, ну так вы уточняйте, что говорите про Андроид В Java информация о мониторе хранится в mark word, потенциально вместе с кэшированным identity hash code, и служебной информацией GC.
Здравствуйте, webserg, Вы писали:
W>Лок могут захватить кто угодно, так как доступ к объкту класса публичный. И надо следить везде где объект используется, то есть по всему приложению, правильно ли его синхронизируют и не будет ли deadlock. А если объявить просто приватный объект и использовать его для монитора, то все видно в одном классе.
Ну могут, и что с того? А дайте ка мне хоть один на 100% безопасный базовый инструмент синхронизации.
volatile безопасен? Нет, ведь нерадивый программист может изменить поле volatile объекта, подумав, что volatile распространяется и на, все что находится внутри объекта.
final безопасен? Нет, ведь нерадивый программист может потерять гарантии final, если из места обращения к final полю у него будет доступна ссылка на это же поле, но без final семантики.
А ReentrantLock безопасен? Нет, ведь программист может взять лок одном потоке, а отпустить в другом, и, не приведи господь, получить IllegalMonitorStateException!
Безопасных инструментов нет. Более того, они и не нужны. Нужны инструменты, которые легко освоить и легко применять. И synchronized как раз таким и является. А если кто-то не умеет его использовать — пускай почитает соответствующую литературу
final безопасен? Нет, ведь нерадивый программист может потерять гарантии final, если из места обращения к final полю у него будет доступна ссылка на это же поле, но без final семантики.
Здравствуйте, devcoach, Вы писали:
D>Здравствуйте, A13x, Вы писали:
A>>https://github.com/android/platform_dalvik/blob/master/vm/oo/Object.h D>А, ну так вы уточняйте, что говорите про Андроид В Java информация о мониторе хранится в mark word, потенциально вместе с кэшированным identity hash code, и служебной информацией GC.
В данном случае у меня, видимо, устаревшая информация — в Oracle/Open JDK все сложнее, там куча оптимизаций поверх этих блокировок — типа переписывания части заголовка объекта при блокировки
Здравствуйте, devcoach, Вы писали:
D>Ну на не-final поляк синхронизироваться то как раз абсолютно нормально.
Почему?
D>А вот возможность синхронизации на некоторых классах java.* может сбить с толку некоторых новичков в многопоточности, да.
Даже на классах своего проекта. Если они публичные, да ещё и используются слишком интенсивно, то шанс выхватить косяк аналогичный.
Здравствуйте, Hard_Club, Вы писали:
H_C>Кто-нибудь знает истинную причину почему разработчики языка не ввели отдельный объкт монитор, а объеденили его с Object?
Здравствуйте, halo, Вы писали:
H>Не совсем по теме, но наверняка будет кому-то интересно: http://msmvps.com/blogs/jon_skeet/archive/2008/12/05/redesigning-system-object-java-lang-object.aspx — Скит рассуждает о наличии слишком обобщённых методов в Java:java.lang.Object, так и в .NET:System.Object, который, к сожалению, повторил те же ошибки.
Очень по теме. Полностью повторяет моё мнение высказаное выше.
Monitors and threading
This is possibly my biggest gripe. The fact that every object has a monitor associated with it was a mistake in Java, and was unfortunately copied in .NET. This promotes the bad practice of locking on "this" and on types — both of which are typically publicly accessible references. I believe that unless a reference is exposed explicitly for the purpose of locking (like ICollection.SyncRoot) then you should avoid locking on any reference which other code knows about. I typically have a private read-only variable for locking purposes. If you're following these guidelines, it makes no sense to be able to lock on absolutely any reference — it would be better to make the Monitor class instantiable, and make Wait/Pulse/PulseAll instance members. (In Java this would mean creating a new class and moving Object.wait/notify/notifyAll members to that class.)