From a94635cdf23236f103029f722faf33d9fa2c8d25 Mon Sep 17 00:00:00 2001 From: Egor Baranov <49813134+egor-baranov@users.noreply.github.com> Date: Fri, 10 Feb 2023 01:25:27 +0300 Subject: [PATCH] Update concurrency.md --- concurrency.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concurrency.md b/concurrency.md index 78d3db7..f4a1d20 100644 --- a/concurrency.md +++ b/concurrency.md @@ -784,7 +784,7 @@ __busy spin__ – это техника, которую программисты + Всегда давайте значимые имена своим потокам. Процесс отладки, нахождения ошибок или отслеживание исключения в многопоточном коде – довольно сложная задача. `OrderProcessor`, `QuoteProcessor` или `TradeProcessor` намного информативнее, чем `Thread1`, `Thread2` и `Thread3`. Имя должно отражать задачу, выполняемую данным потоком. + Избегайте блокировок или старайтесь уменьшить масштабы синхронизации. Блокировка затратна, а переключение контекста ещё более ресурсоёмко. Пытайтесь избегать синхронизации и блокировки насколько это возможно, и организуйте критическую секцию в минимально необходимом объёме. Поэтому синхронизированный блок всегда предпочительней синхронизированного метода, дополнительно наделяя возможностью абсолютного контроля над масштабом блокировки. + Обрабатывайте прерывание потока с особой тщательностью. Нет ничего хуже оставшегося заблокированным ресурса или системы в неконстистентном, по причине неподтверждённой транзакции, состоянии. -+ Помните об обработке исключений. Выброшенные `InterruptedException` должны быть адекватно обработаны, а не просто подавлены. Так же не стоит пренебрегать `Thread.UncaughtExceptionHandler`. При использовании пула потоков необходимо помнить, что он зачастую просто «проглатывает» исключения. Так, если вы отправили на выполнение `Runnable` нужно обязательно поместить код выполнения задачи внутрь блока `try-catch`. Если в очередь пула помещается `Callable`, необходимо удостоверится, что результат выполнения всегда изымается помощью блокирующего `get()`, чтобы в случае возникновения существовала возможнотсь заново выбросить произошедшее исключение. ++ Помните об обработке исключений. Выброшенные `InterruptedException` должны быть адекватно обработаны, а не просто подавлены. Так же не стоит пренебрегать `Thread.UncaughtExceptionHandler`. При использовании пула потоков необходимо помнить, что он зачастую просто «проглатывает» исключения. Так, если вы отправили на выполнение `Runnable` нужно обязательно поместить код выполнения задачи внутрь блока `try-catch`. Если в очередь пула помещается `Callable`, необходимо удостоверится, что результат выполнения всегда изымается помощью блокирующего `get()`, чтобы в случае возникновения существовала возможность заново выбросить произошедшее исключение. + Между синхронизаторами и `wait()` и `notify()` следует выбирать синхронизаторы. Во-первых, синхронизаторы, типа `CountDownLatch`, `Semaphore`, `CyclicBarrier` или `Exchanger` упрощают написание кода. Очень сложно реализовывать комплексный управляющий поток, используя `wait()` и `notify()`. Во-вторых, эти классы написаны и поддерживаются настоящими мастерами своего дела и есть шанс, что в последующих версиях JDK они будут оптимизированы изнутри или заменены более производительной внешней реализацией. + Почти всегда использование Concurrent сollection выгоднее использования Synchronized сollection, т.к. первые более современны (используют все доступные на момент их написания новшества языка) и масштабируемы, чем их синхронизированые аналоги.