Здравствуйте, коллеги!
Статья, перевод которой мы предлагаем сегодня, в очередной раз напоминает о важности нестареющей книги "Java Concurrency in practice" под авторством Брайана Гёца (Brian Goetz).
Даты комментариев к этой статье в оригинале подсказывают, что автор обновляет и заново публикует ее не в первый раз. Поэтому мы позволили себе также обновить ссылку на упоминаемую в статье книгу Рауля-Габриэля Урма, Марио Фуско и Алана Майкрофта, которая выходила в издательстве «Manning» под названием «Java 8 in Action». У нас готовится перевод нового издания под названием «Modern Java». Но пока давайте поговорим о классике. Вы приглашаетесь под кат.
Читатель под ником Shobhit задал мне этот вопрос в комментариях к статье о 12 продвинутых книг по Java для программистов среднего уровня – часть 1. Вопрос в самом деле хороший, и, думаю, у многих Java-программистов возникали подобные сомнения, когда в наше время кто-нибудь рекомендовал им прочесть «Java Concurrency in Practice». Когда эта книга только вышла, в 2006 году, весь мир Java еще никак не мог разобраться с нововведениями в области конкурентности, сделанными в Java 1.5. Думаю, тогда была предпринята первая серьезная попытка улучшить в Java встроенную поддержку многопоточности и конкурентности. Тогда многие программисты еще даже не подозревали о новых инструментах, появившихся в API, например о CountDownLatch, CyclicBarrier,
Именно таково общее представление об этой книге, и в таком ключе опишут ее вам многие разработчики, если вы спросите «А как вам «Java Concurrency in Practice»»? Однако, я воспринимаю эту книгу немного иначе, и именно поэтому до сих пор рекомендую ее всем новичкам, знакомящимся с Java, либо разработчикам среднего уровня, желающим освоить концепции, связанные с конкурентностью.
Важнейший материал, с которым вас познакомит эта книга – четкие концепции и основы конкурентного программирования, в частности, видимость, упорядочивание, потокобезопасность, неизменяемость, параллелизм, т.д.
Также она объясняет, почему в большинстве случаев конкурентные приложения на Java пишутся неправильно, почему Java-программисты допускают распространенные ошибки, приводящие к проблемам с многопоточностью, среди которых: условия гонки, мертвая блокировка, активная блокировка, интерференция в памяти и просто некорректные вычисления.
В книге используются эмотиконы, сопровождающие описание «как делать неправильно», прежде, чем познакомить читателя с верным и качественным решением проблемы. Так книга не только помогает бороться с заблуждениями, которые сохраняются у многих Java-разработчиков, но и прививать в Java-сообществе верную информацию о том, как работать с многопоточностью и конкурентностью.
Вне всяких сомнений, многопоточность и конкурентность сложны. Их нелегко правильно реализовать в коде, не менее трудно понять и объяснить. Я знаю много программистов, попросту не способных наглядно изобразить, как разные потоки взаимодействуют с одним и тем же элементом кода, оперируя разными данными.
Как и классический пример с рекурсией, одним программистам многопоточность очень легко дается на практике, а другим многопоточность сложно осмыслить и применить в прикладном сценарии.
Наибольший вклад книги Java Concurrency in Practice в развитие мира Java заключается не в том, чтобы упростить конкурентность, а в том, чтобы дать о ней верную и точную информацию, которой не хватало. С тех пор я провел множество собеседований и знаю, что программисты всегда не вполне точно представляют себе устройство потоков и то, как они работают.
Многие программисты, даже успевшие поработать с Java 4-5 лет, не понимают, как устроены изменчивые переменные; все, что они знают – что при работе с изменчивой переменной нужно при каждом сравнении проверять, какое значение находится в основной памяти. Это правда, но только часть правды.
Им не рассказывали о модели памяти Java, о том, как изменчивая переменная может влиять на порядок следования кода и выполнение вычислительных инструкций в его основе. Речь о применении динамической компиляции (JIT) и виртуальной машины Java (JVM) для оптимизации; такая оптимизация может приводить к тонким логическим ошибкам.
Людям не рассказывают, как изменчивые переменные позволяют увидеть, что было сделано в одном потоке, прежде чем обращаться к переменной из другого потока и пр. Не все знают, что такое барьер памяти, и как он влияет на видимость.
Именно по книге Java Concurrency in Practice многие Java-программисты изучили все эти концепции. Должен признать, что и сам я, пока не прочитал ее, во многом заблуждался по поводу многих существенных вопросов многопоточности и конкурентности, в частности, порядка следования, видимости и неявных эффектов со стороны финальных переменных и безопасной публикации. Книга помогла мне во всем этом разобраться.
Кстати, если какие-то разделы книги покажутся вам немного непонятными – поверьте, не вам одному. Здесь следует поблагодарить доктора Хайнца Кабуца (Heinz Kabutz), изложившего материал книги в упрощенном виде в своем курсе Java Concurrency in Practice Bundle.
Если даже этот материал покажется вам слишком сложным – у Хайнца есть и другой курс, Mastering Threads, помогающий разобраться в многопоточности любому среднестатистическому Java-программисту.
Теперь давайте поговорим о Java 8, то есть, о том, что изменилось от Java 1.5 до Java 8. В JDK появилось множество новых инструментов для внедрения конкурентности и проектирования более качественных конкурентных приложений Java. В JDK 7 появился пул fork-join, в Java 8 –
Также у нас появились потоки (stream) и параллельные потоки (parallel streams), позволяющие разработчикам пользоваться преимуществами конкурентности, не программируя ее. Вся идея о том, чтобы забрать реализацию конкурентности у разработчиков приложений и перепоручить ее разработчикам API немного упрощает ситуацию с конкурентностью в Java и снижает риски при ее внедрении.
Также это означает, что в Java можно выполнять массовые операции во множестве потоков при помощи всего пары методов, и не писать при этом ни единой строки кода, связанной с потоками, ключевым словом synchronized или методами ожидания и уведомления (wait-notify).
Несомненно, любому Java-разработчику требуется изучить эти новые инструменты, чтобы не отставать развития технологии – в чем, конечно, очень поможет книга вроде «Modern Java In Action». Она не только познакомит вас со всеми нововведениями языка Java, но и поможет научиться использовать их при выполнении повседневных задач, понять мотивацию этих нововведений и получить общее представление о современном языке Java.
Хотя, книга Java Concurrency in Practice в ее текущем виде не освещает всех этих важных концепций и инструментов, она все равно остается бесценной для изучения ключевых возможностей языка Java, связанных с потоками, конкурентностью и многопоточностью.
Книга Гёца по-прежнему обязательна к прочтению для любого Java-разработчика, желающего изучить и освоить многопоточность и конкурентность – самые сильные стороны Java при разработке приложений.
С учетом всего вышесказанного я, как и многие Java-разработчики по всему миру, хотел бы увидеть и обновленное издание Java Concurrency in Practice, где рассматривались бы инструменты и методологии, появившиеся в Java 6, 7, 8, 9, 10 и может быть даже в Java 11. Ведь появились обновленные версии Effective Java и Head First design patterns, рассматривающие Java 8 и демонстрирующие, насколько проще реализовывать различные паттерны при помощи новых возможностей Java 8.
Статья, перевод которой мы предлагаем сегодня, в очередной раз напоминает о важности нестареющей книги "Java Concurrency in practice" под авторством Брайана Гёца (Brian Goetz).
Даты комментариев к этой статье в оригинале подсказывают, что автор обновляет и заново публикует ее не в первый раз. Поэтому мы позволили себе также обновить ссылку на упоминаемую в статье книгу Рауля-Габриэля Урма, Марио Фуско и Алана Майкрофта, которая выходила в издательстве «Manning» под названием «Java 8 in Action». У нас готовится перевод нового издания под названием «Modern Java». Но пока давайте поговорим о классике. Вы приглашаетесь под кат.
Читатель под ником Shobhit задал мне этот вопрос в комментариях к статье о 12 продвинутых книг по Java для программистов среднего уровня – часть 1. Вопрос в самом деле хороший, и, думаю, у многих Java-программистов возникали подобные сомнения, когда в наше время кто-нибудь рекомендовал им прочесть «Java Concurrency in Practice». Когда эта книга только вышла, в 2006 году, весь мир Java еще никак не мог разобраться с нововведениями в области конкурентности, сделанными в Java 1.5. Думаю, тогда была предпринята первая серьезная попытка улучшить в Java встроенную поддержку многопоточности и конкурентности. Тогда многие программисты еще даже не подозревали о новых инструментах, появившихся в API, например о CountDownLatch, CyclicBarrier,
ConcurrentHashMap
и многих других. Книга служила им отлаженным введением в работу с этими инструментами, рассказывала, как с их помощью можно писать высокопроизводительные конкурентные приложения Java.Именно таково общее представление об этой книге, и в таком ключе опишут ее вам многие разработчики, если вы спросите «А как вам «Java Concurrency in Practice»»? Однако, я воспринимаю эту книгу немного иначе, и именно поэтому до сих пор рекомендую ее всем новичкам, знакомящимся с Java, либо разработчикам среднего уровня, желающим освоить концепции, связанные с конкурентностью.
Важнейший материал, с которым вас познакомит эта книга – четкие концепции и основы конкурентного программирования, в частности, видимость, упорядочивание, потокобезопасность, неизменяемость, параллелизм, т.д.
Также она объясняет, почему в большинстве случаев конкурентные приложения на Java пишутся неправильно, почему Java-программисты допускают распространенные ошибки, приводящие к проблемам с многопоточностью, среди которых: условия гонки, мертвая блокировка, активная блокировка, интерференция в памяти и просто некорректные вычисления.
В книге используются эмотиконы, сопровождающие описание «как делать неправильно», прежде, чем познакомить читателя с верным и качественным решением проблемы. Так книга не только помогает бороться с заблуждениями, которые сохраняются у многих Java-разработчиков, но и прививать в Java-сообществе верную информацию о том, как работать с многопоточностью и конкурентностью.
Вне всяких сомнений, многопоточность и конкурентность сложны. Их нелегко правильно реализовать в коде, не менее трудно понять и объяснить. Я знаю много программистов, попросту не способных наглядно изобразить, как разные потоки взаимодействуют с одним и тем же элементом кода, оперируя разными данными.
Как и классический пример с рекурсией, одним программистам многопоточность очень легко дается на практике, а другим многопоточность сложно осмыслить и применить в прикладном сценарии.
Наибольший вклад книги Java Concurrency in Practice в развитие мира Java заключается не в том, чтобы упростить конкурентность, а в том, чтобы дать о ней верную и точную информацию, которой не хватало. С тех пор я провел множество собеседований и знаю, что программисты всегда не вполне точно представляют себе устройство потоков и то, как они работают.
Многие программисты, даже успевшие поработать с Java 4-5 лет, не понимают, как устроены изменчивые переменные; все, что они знают – что при работе с изменчивой переменной нужно при каждом сравнении проверять, какое значение находится в основной памяти. Это правда, но только часть правды.
Им не рассказывали о модели памяти Java, о том, как изменчивая переменная может влиять на порядок следования кода и выполнение вычислительных инструкций в его основе. Речь о применении динамической компиляции (JIT) и виртуальной машины Java (JVM) для оптимизации; такая оптимизация может приводить к тонким логическим ошибкам.
Людям не рассказывают, как изменчивые переменные позволяют увидеть, что было сделано в одном потоке, прежде чем обращаться к переменной из другого потока и пр. Не все знают, что такое барьер памяти, и как он влияет на видимость.
Именно по книге Java Concurrency in Practice многие Java-программисты изучили все эти концепции. Должен признать, что и сам я, пока не прочитал ее, во многом заблуждался по поводу многих существенных вопросов многопоточности и конкурентности, в частности, порядка следования, видимости и неявных эффектов со стороны финальных переменных и безопасной публикации. Книга помогла мне во всем этом разобраться.
Кстати, если какие-то разделы книги покажутся вам немного непонятными – поверьте, не вам одному. Здесь следует поблагодарить доктора Хайнца Кабуца (Heinz Kabutz), изложившего материал книги в упрощенном виде в своем курсе Java Concurrency in Practice Bundle.
Если даже этот материал покажется вам слишком сложным – у Хайнца есть и другой курс, Mastering Threads, помогающий разобраться в многопоточности любому среднестатистическому Java-программисту.
Теперь давайте поговорим о Java 8, то есть, о том, что изменилось от Java 1.5 до Java 8. В JDK появилось множество новых инструментов для внедрения конкурентности и проектирования более качественных конкурентных приложений Java. В JDK 7 появился пул fork-join, в Java 8 –
CompleteableFutures
. Гораздо важнее, что, начиная с Java 8, стал закрепляться новый, более функциональный стиль программирования, обеспечиваемый при помощи лямбда-выражений. Также у нас появились потоки (stream) и параллельные потоки (parallel streams), позволяющие разработчикам пользоваться преимуществами конкурентности, не программируя ее. Вся идея о том, чтобы забрать реализацию конкурентности у разработчиков приложений и перепоручить ее разработчикам API немного упрощает ситуацию с конкурентностью в Java и снижает риски при ее внедрении.
Также это означает, что в Java можно выполнять массовые операции во множестве потоков при помощи всего пары методов, и не писать при этом ни единой строки кода, связанной с потоками, ключевым словом synchronized или методами ожидания и уведомления (wait-notify).
Несомненно, любому Java-разработчику требуется изучить эти новые инструменты, чтобы не отставать развития технологии – в чем, конечно, очень поможет книга вроде «Modern Java In Action». Она не только познакомит вас со всеми нововведениями языка Java, но и поможет научиться использовать их при выполнении повседневных задач, понять мотивацию этих нововведений и получить общее представление о современном языке Java.
Хотя, книга Java Concurrency in Practice в ее текущем виде не освещает всех этих важных концепций и инструментов, она все равно остается бесценной для изучения ключевых возможностей языка Java, связанных с потоками, конкурентностью и многопоточностью.
Книга Гёца по-прежнему обязательна к прочтению для любого Java-разработчика, желающего изучить и освоить многопоточность и конкурентность – самые сильные стороны Java при разработке приложений.
С учетом всего вышесказанного я, как и многие Java-разработчики по всему миру, хотел бы увидеть и обновленное издание Java Concurrency in Practice, где рассматривались бы инструменты и методологии, появившиеся в Java 6, 7, 8, 9, 10 и может быть даже в Java 11. Ведь появились обновленные версии Effective Java и Head First design patterns, рассматривающие Java 8 и демонстрирующие, насколько проще реализовывать различные паттерны при помощи новых возможностей Java 8.