Избегайте избыточной синхронизации

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

для исключения возможности взаимной блокировки (deadlock) никогда не передавайте управление клиенту, если находитесь в синхронизированном методе или блоке. Иными словами, из области синхронизации не следует вызывать открытые или защищенные методы, которые предназначены для переопределения. (Такие методы обычно являются абстрактными, но иногда по умолчанию могут иметь определенную реализацию.) С точки зрения класса, содержащего синхронизированную область, такой метод является чужим. У класса нет сведений о том, что этот метод делает, нет над ним контроля. Клиент может реализовать этот метод таким образом, чтобы он создавал другой поток, выполняющий обратный вызов этого же класса. Затем вновь созданный поток может попытаться получить доступ к области, блокированной первым потоком, что приведет к блокировке нового потока. И если метод, создавший новый поток, ждет его завершения, возникает взаимная блокировка.

для пояснения рассмотрим класс, в котором реализована очередь заданий (work queue). Этот класс позволяет клиентам ставить задания в очередь на асинхронную обработку. Метод enqueue может вызываться столь часто, сколь это необходимо. Конструктор класса запускает фоновый поток, который удаляет из очереди записи в том порядке, в котором они были сделаны, и обрабатывает их, используя метод processItem. Если очередь заданий больше не нужна, клиент вызывает метод stop, чтобы заставить поток изящно остановиться после завершения всех заданий, находящихся в обработке.

public abstract class WorkQueue {

private final List queue = new LinkedList();

private boolean stopped = false;

Creating a Redundant Ableton Live Rig


Читать еще…

Понравилась статья? Поделиться с друзьями: