Archive for category Core Java

Выжимки из книги Java Concurrency in Practice (часть 1)

Что такое поток?

Поток – это легковесный процесс.

Преимущества использования потоков

  1. Использование нескольких ядер или процессоров повышает пропускную способность за счет более эффективного использования ресурсов процессора/процессоров.
  2. Уменьшение времени ожидания ресурсов. Один ресурс ожидает завершения операции I/O, другой может в это время использовать процессор.
  3. Использование потоков упрощает моделирование. Примеры: Servlet, RMI.
  4. Использование потоков упрощает обработку асинхронных событий.
  5. Более отзывчивый GUI. Event Dispatcher Thread (EDT).

Риски, которые возникают при использовании потоков

  1. Угрозы безопасности. Порядок операций в многопоточной программе непредсказуем. Пример: i++ состоит из трех операций – чтение, инкремент, запись. Race condition – состояние гонки. Потоки делят адресное пространство.
  2. Угрозы жизнеспособности. Безопасность – “ничего плохого не происходит”. Liveness (жизнеспособность) – “что-то хорошее в конце концов происходит”. Один из самых известных видов liveness-угроз – deadlock – когда потоки не могут продолжить выполнение и не могут завершиться в результате взаимной блокировки. Другие примеры угроз жизнеспособности: starvation – голодная смерть, голодание; livelock – активная блокировка.
  3. К жизнеспособности прямое отношение имеет производительность. Что-то хорошее не только должно происходить, но должно происходить быстро. Проблемы, которые нужно рассмотреть при разработке многопоточного приложения: малый срок службы, отзывчивость, пропускная способность, потребление ресурсов, масштабируемость. Частое переключение контекста может быть нежелательным и отрицательно влиять на производительность.

Фреймворки приносят многопоточность в приложения посредством вызова компонентов приложения из потоков фреймворка.

Потокобезопасность

shared – переменная может быть доступна из множества потоков.

mutable – значение может изменяться во время жизненного цикла объекта.

Написание многопоточного кода – это не только забота о потоках и блокировках. Написание многопоточного кода – это управление доступом к состоянию, в частности к раздеяемому (shared) и изменяющемуся (mutable) состоянию. Состояние объекта – это данные, сохраненные в переменных состояния (state variables) – в полях экземпляра или в статических полях. Состояние объекта может складываться из полей, которые находятся в других, связанных, объектах.

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

Механизм синхронизации в Java подразумевает использование ключевого слова synchronized, которое предоставляет эксклюзивную блокировку, однако к понятию “синхронизация” также относятся такие вещи как volatile-переменные, явные блокировки, и атомарные переменные.

Если несколько потоков имеют доступ к изменяемой переменной состояния без синхронизации, значит программа не корректна. Это можно исправить тремя способами:

  1. Не разделять переменную состояния между потоками.
  2. Сделать переменную состония неизменной.
  3. Использовать синхронизацию.

Намного проще проектировать класс потокобезопасным, чем модифицировать его позже.

При разработке потокобезопасного класса, хорошие техники объектно-ориентрированного проектировани – инкапсуляция, неизменность и чистая спецификация инвариантов – ваши лучшие друзья.

Источники

  1. Java Concurrency in Practice. Brian Goetz.

Tags:

Потоки в Java. Часть 3.

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

В этой части мы рассмотрим взаимодействие потоков и методы для работы с потоками, которые находятся в классе Object.
Read the rest of this entry »

Tags:

Потоки в Java. Часть 2.

В предыдущей статье мы дали определение потокам в Java, научились определять потоки с помощью расширения класса java.lang.Thread и реализации интерфейса java.lang.Runnable, инстанцировать потоки и запускать их.

Также мы рассмотрели как выполняется несколько потоков, немного поговорили о планировщике потоков и закончили первую часть рассмотрением состояний потоков и переходов между их состояниями.

В этой статье мы продолжим рассматривать тему потоков в Java. А именно, мы рассмотрим каким образом можно приостановить выполнение потока, разберемся с приоритетами, научимся соединять потоки в цепочку (join), и рассмотрим большую и важную тему – синхронизацию кода. Начнем.
Read the rest of this entry »

Tags:

Потоки в Java. Часть 1.

17 апреля 2010 года в Москве, в офисе Яндекса, ул. Льва Толстого, 16, состоится встреча JUG.RU на которой выступит Евгений Кирпичёв с докладом “Многопоточное программирование и Java: корректность, паттерны, оптимизация”.

Цель доклада — расширить кругозор слушателей в области методик разработки многопоточных программ:

  1. формальные рассуждения о корректности
  2. способствующие ей приёмы проектирования
  3. способы тестирования
  4. вопросы эффективности
  5. инструментарий
  6. интересные средства многопоточного программирования из других языков

Для регистрации пришлите свою фамилию и имя на русском языке на yasha@telamon.ru?subject=17_April_2010. Регистрация мягкая, достаточно просто послать письмо, подтверждения не высылаются. После официальной части планируется совместное посещение бара для неформального общения.

Цель этого поста – вспомнить все про потоки в Java. С помощью этой статьи также можно подготовиться к сдаче экзамена SCJP 6 так как в ней рассматриваются все вопросы, которые могут возникнуть на экзамене по теме “потоки в Java”. Поехали!
Read the rest of this entry »

Tags: