В статье (http://programmersnook.blogspot.com/2012/05/java.html) с примерами рассматриваются основные возможности Java в области параллелизма, анализируются проблемы которые поддержка параллелизма призвана решить и приводятся некоторые детали реализации. Большинство из приведенной информации актуально для Java 6 и 7.URL: http://programmersnook.blogspot.com/2012/05/java.html
Новость: http://www.opennet.me/opennews/art.shtml?num=33835
Спасибо, оценю качество статьи, вот еще на тему http://www.youtube.com/watch?v=cgXC09uwxIQ
Суть проблемы Java и многопоточность в том, что все объекты передаются по ссылке. В Erlang, например (и во многих остальных функциональных языках), все объекты передаются по значению. Т.о. нет разделяемых областей памяти и проблем нет.P.S.
Есть http://code.google.com/p/disruptor/ .На LMAX на одном сервере 1000000 запросов в секунду обрабатывается. Стандартными средствами намного меньше. И всё из-за ОС, т.к. дорого обходится парковка и пробуждение потоков. Ну, а со стороны Java GC может помешать. В Disruptor потоки не wait-ятся и новые объекты не создаются. Очередь сообщений тоже строго фиксированного размера(кольцевой буфер), что не вызывает сборку мусора для данных объектов.
ну да как только все обекты передаются по значению возникает другая проблема, пропускная способность памяти )
Rust лишен обоих проблем.
> http://code.google.com/p/disruptor/Очень интересная штука. Буду знать. Спасибо.
> Суть проблемы Java и многопоточность в том, что все объекты передаются по ссылке.Протестую! В Java объекты передаются копиями ссылок и ведётся учёт времени жизни этих копий ссылок, а через них — времени жизни объекта, на который они ссылаются.
ну вообще-то подсчет ссылок дорогая операция, поэтому сборщик работает по другому:1. имеется набор объектов которые доступны всегда + константные объекты, это все называется Root Set
2. на паузе (stop the world) проверяется на какие объекты ссылаются объекты из этого набора
3. проходим так нужное количество итераций, до тех пор пока не дойдем до объектов которые ни на кого не ссылаются
4. все объекты которые мы не пометили попадают под сборкуТак же данный метод избавлен от главного недостатка метода с подсчетом ссылок: кольцевые зависимости (А ссылается на Б, Б ссылается на А)
По поводу диструптора:
1. магия не только в кольцевом буфере (смотрим доклад с недавнего JavaDay в питере), обычную очередь можно разогнать до сопоставимых результатов
2. да, парковка дорогая операция, поэтому они жгут циклы процессора, лишь бы не останавливаться
3. дополнительная магия их скорости в том что пауз на сборке у них просто нету, так как используют Azule (далеко не у всех такие деньги будут)
> ну вообще-то подсчет ссылок дорогая операцияА я и не говорил про подсчёт. Подсчёт — это частный, далеко не самый эффективный случай УЧЁТА ссылок.
Объекты в Java передаются копиями ссылок (copy of reference). Ссылки передаются собственными значениями (reference by-value). (Во загнул! Но так оно и есть на самом деле). :)
>> ну вообще-то подсчет ссылок дорогая операция
> А я и не говорил про подсчёт. Подсчёт — это частный, далеко
> не самый эффективный случай УЧЁТА ссылок.
> Объекты в Java передаются копиями ссылок (copy of reference). Ссылки передаются собственными
> значениями (reference by-value). (Во загнул! Но так оно и есть на
> самом деле). :)ну тогда извиняюсь если я неправильно понял, что подразумевалось под УЧЁТОМ
Кстати, да. Циклы процессора расходуются впустую, поэтому не для всяких сообщений эффект будет одинаковым. Если очень много мелких сообщений, то проще тратить циклы процессора, чем останавливать поток.
А в Erlang, если не путаю, потоки легковесные и на потоки ОС напрямую не мапятся. Если на текущем процессоре ресурсы кончаются, то порождается новый поток ОС, который обслуживает несколько легковесных потоков Erlang-а.
> Суть проблемы Java и многопоточность в том, что все объекты передаются по
> ссылке. В Erlang, например (и во многих остальных функциональных языках), все
> объекты передаются по значению. Т.о. нет разделяемых областей памяти и проблем
> нет.про память уже сказали, плодить каждый раз по объекту при передачи далеко не всегда разумно
в том же clojure спокойно реализовали Software-Transactional Memory и передают по ссылкеИдем дальше: shared immutable объекты - используем объект в качестве параметра, но изменять его нет возможности, нам из него данные получать, зачем для этого плодить новый объект ?
Вопрос ведь не в том: можно или нельзя на java писать многопоточный код, а в уровне знаний необходимый для этого.
Можно просто накидать блоков синхронизаций и локов - получишь печальку,
сделаешь по умному с отсутвсием разделяемых объектов, а если и разделяемымы то обязательно неизменяемыми - коду не на чем будет бороться за ресурсы и избавляешься от проблем синхронизации, все работает быстро и красиво