Разделяемые ресурсы, конфликты, проблема совместного доступа - 1

— Привет, Амиго! Хочу тебе рассказать о совместном использовании ресурсов. Разными нитями, ясное дело.

Я все время говорю о проблемах при работе нескольких нитей и о том, как их решать. Это не значит, что использование нитей – это плохо. Нити – это очень мощный инструмент. Фактически, они позволяют увеличить скорость, и даже надежность работы твоей программы. Чем сложнее программа – тем больше в ней нитей и различных самостоятельных частей.

Разбиение программы на независимые (слабосвязанные) части очень выгодно.

Представь, что твоя программа внутри разбита на 100 нитей. Но у тебя всего двухъядерный процессор. Это значит, что на каждом ядре исполняется в среднем 50 нитей.

Если же тебе нужно нарастить мощность программы, ты просто покупаешь двухпроцессорный сервер и пару крутых процессоров для него. В результате у него суммарно может быть до 32- ядер, и производительность твоей программы может вырасти в 2-20 раз. В зависимости от того, насколько действительно независимых частей она разбита.

Это одна из причин доминирования Java в секторе Enterprise-разработки. Если у компании есть сложная программа для внутренних нужд, которую пишут 20 разработчиков, то купить еще один сервер гораздо дешевле, чем ускорить программу в 2 раза.

— Так вот оказывается в чем дело.

— Но! Каждый раз, когда разработчик решает использовать еще одну нить, он решает одну проблему, а создает две. Слишком много нитей не увеличат производительность программы до бесконечности.

Во-первых, в любой программе есть работа, которую невозможно разбить на части и выполнять параллельно в разных нитях. Во-вторых, все нити выполняются на одном и том же процессоре. Чем больше нитей, тем медленнее работает каждая из них.

И, самое главное – нити часто используют одни и те же объекты (их обычно называют разделяемыми ресурсами).

Например, нить хочет сохранить в файл информацию о сделанной работе. Если таких нитей несколько, и они хотят записать информацию в один файл – они будут мешать друг другу. Чтобы в файле не было мешанины, каждая нить пользуется уникальным доступом к файлу – т.е. пока файлом пользуется одна нить, другие ждут.

— Да, я помню, это делается с помощью ключевого слова synchronized.

— Да, именно.

— А если нити пишут в разные файлы?

— Формально – это разные объекты, но жесткий диск же один.

— Т.е. реально что-то распараллелить можно только внутри процессора?

— Формально – Да, как только твоей нити надо что-то еще кроме данных, которые у нее есть, это что-то уже может быть занято другой нитью и придется ждать.

— И что же делать? Как узнать – делать много нитей или нет?

— Это определяется непосредственно архитектурой программы. У любого проекта есть его «архитектор», который знает все «ресурсы», которые используются в программе, знает их ограничения, и насколько они хорошо/плохо параллелятся.

— А если я не знаю?

— Тут есть два варианта:

а) поработать под началом такого специалиста

б) набить шишек самому

— Я – робот, у меня не бывает шишек – только вмятины.

— Ну, значит, набить вмятин.

— Ясно, спасибо. Ты прояснила некоторые вопросы, о которых я уже начал ломать голову.