Обновление
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Struchkov Mark 2024-10-09 09:23:45 +03:00
parent 8ce575f586
commit be8fd578f3
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
51 changed files with 449 additions and 29 deletions

View File

@ -19,11 +19,11 @@ public List<User> getUsersByType(String userType, Set<Long> userIds)
- При изменении параметров, ключ кэширования также должен изменяться. В данном случае, если изменятся значения аргументов `userType` и `userIds`, мы должны получить новое значение ключа.
- По параметрам ключ должен определяться однозначно, то есть для одних и тех же значений аргументов ключ кэширования должен принимать только одно значение. Иначе мы рискуем понизить эффективность процесса кэширования, создавая несколько кэшей для одной и той же выборки.
Сформируем ключ кэширования для нашего метода. В качестве хранилища будем использовать [[Redis]].
Сформируем ключ кэширования для нашего метода. В качестве хранилища будем использовать [[../../../../../wiki/zero/00 Redis]].
В начале ключа я обычно обязательно указываю какой-то уникальный префикс сервиса, чтобы не получить коллизию между разными сервисами. Пускай в данном случае префикс будет `USER_SERVICE`. Также добавляю уникальный префикс метода, в данном случае будет `USERS`.
В качестве разделителей рекомендую использовать `:`, в [[../../../../../_inbox/Redis|Redis]] это позволяет визуально сгруппировать ключи. Это позволяет визуально группировать ключи при использовании UI клиента. Таким образом начало нашего ключа выглядит следующим образом: `USER_SERVICE:USERS:`.
В качестве разделителей рекомендую использовать `:`, в [[../../../../../wiki/zero/00 Redis|00 Redis]] это позволяет визуально сгруппировать ключи. Это позволяет визуально группировать ключи при использовании UI клиента. Таким образом начало нашего ключа выглядит следующим образом: `USER_SERVICE:USERS:`.
Значения аргументов метода также должны попасть в ключ. Возьмем наш первый аргумент `String userType`. Для аргумента также можно использовать префиксы, но это не обязательно. В данном случае пусть будет `USER_TYPE`. А вот для самого значения параметра есть несколько вариантов:
- Оставить строкой и просто выполнить конкатенацию.

View File

@ -13,10 +13,10 @@ linked:
---
Представим, что у нас 3 реплики сервиса, которые выполняют какие-то вычисления раз в 30 секунд, а в вычислениях используется кэшированные значения. При [[Инвалидация кэша|инвалидации кэша]] может сложиться ситуация при которой все 3 реплики начнут наперегонки обновлять значение в кэше. Это приводит как минимум к лишней нагрузке на базу данных, а как максимум к отказу в обслуживании.
Решить эту проблему можно с использованием [[../../../../../_inbox/Блокировка|блокировок]]:
Решить эту проблему можно с использованием [[../../fundamental/Блокировка|блокировок]]:
- Получаем доступ к кэшу, его срок жизни истёк. Пытаемся заблокироваться по ключу.
- Не удалось получить блокировку
- Ждём снятия [[../../../../../_inbox/Блокировка|блокировки]].
- Ждём снятия [[../../fundamental/Блокировка|блокировки]].
- Если не дождались, возвращаем старые данные кэша
- Если дождались, значит кто-то построил кэш за нас, выбираем значения ключа заново, возвращаем новые данные.
- Удалось получить блокировку

View File

@ -6,6 +6,7 @@ aliases:
- блокирующий ввод-вывод
- блокирующего
- блокирующей операции
- блокирующих операций
tags:
- maturity/🌱
date: 2024-01-28

View File

@ -10,14 +10,14 @@ parents:
- "[[Кэширование]]"
linked:
---
Поход в базу данных может быть достаточно дорогим, в этом случае имеет смысл сохранять данные в кэш. Ускорить сложные запросы может кэширование: мы помещаем результат вычислений в некоторое хранилище (например, [Memcached](Memcached.md) или [Redis](Redis.md)), которое обладает отличными характеристиками по времени доступа к информации. Теперь вместо обращений к медленным, сложным и тяжелым backendам нам достаточно выполнить запрос к быстрому кэшу.
Поход в базу данных может быть достаточно дорогим, в этом случае имеет смысл сохранять данные в кэш. Ускорить сложные запросы может кэширование: мы помещаем результат вычислений в некоторое хранилище (например, [Memcached](Memcached.md) или [00 Redis](../../../../wiki/zero/00%20Redis.md)), которое обладает отличными характеристиками по времени доступа к информации. Теперь вместо обращений к медленным, сложным и тяжелым backendам нам достаточно выполнить запрос к быстрому кэшу.
![](../../meta/files/images/Pasted%20image%2020240617184722.png)
Самые распространенные варианты хранения:
- Хранение в ОЗУ
- [Memcached](Memcached.md)
- [Redis](Redis.md)
- [00 Redis](../../../../wiki/zero/00%20Redis.md)
***
## Мета информация
**Область**:: [[../../meta/zero/00 HighLoad|00 HighLoad]]

View File

@ -5,6 +5,7 @@ aliases:
- хеш функция
- хеш функции
- хеш-функции
- хеш-алгоритм
tags:
- maturity/🌱
date: 2024-09-14

View File

@ -2,22 +2,29 @@
aliases:
- конкурентность
- конкурентна
- конкурентности
tags:
- maturity/🌱
date: 2024-09-10
zero-link:
- "[[../../meta/zero/00 Разработка|00 Разработка]]"
zero-link: []
parents:
linked:
- "[[Parallelism]]"
---
Concurrency - свойство систем, глобальное состояние которых изменяется чередующимся выполнением независимых или частично-независимых функций или компонент. Чередование приводит к [[Переключение контекста|переключению контекста]].
Конкурентность — это общий термин, описывающий способность программы обрабатывать несколько задач. ==Это не обязательно означает одновременное выполнение.==
![[../../meta/files/images/Pasted image 20240910132902.png]]
- [[Parallelism]]. Физическое одновременное выполнение нескольких задач на разных ядрах или процессорах. Параллелизм является формой конкурентности, но требует аппаратной поддержки для одновременного выполнения.
**Механизмы реализации конкурентности**
- [[Многозадачность|Multitasking]].
- [[Multithreading]]. Использование нескольких потоков внутри одного процесса. Потоки могут выполняться конкурентно, разделяя память и ресурсы процесса. Также требует механизма переключения контекстов, но на уровне потоков.
- [[Асинхронное программирование]]
- [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]]
![[../../meta/files/images/Pasted image 20241008204058.png]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Родитель**:: [[Многозадачность|Multitasking]]
**Источник**::
**Создана**:: [[2024-09-10]]
**Автор**::
@ -25,3 +32,6 @@ Concurrency - свойство систем, глобальное состоян
- [[Parallelism]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Многозадачность]]
<!-- SerializedQuery END -->

View File

@ -8,7 +8,7 @@ zero-link:
parents:
linked:
---
Copy-on-Write (COW) — это техника оптимизации управления памятью, используемая в [[../../../../knowledge/dev/pc/Операционная система|операционных системах]] для эффективного копирования данных, особенно в контексте [[Многозадачность ЦПУ|многозадачности]] и управления виртуальной памятью. Этот метод позволяет нескольким процессам совместно использовать одну и ту же страницу памяти до тех пор, пока данные не нужно будет изменить, что экономит ресурсы и ускоряет выполнение программ.
Copy-on-Write (COW) — это техника оптимизации управления памятью, используемая в [[../../../../knowledge/dev/pc/Операционная система|операционных системах]] для эффективного копирования данных, особенно в контексте [[Многозадачность|многозадачности]] и управления виртуальной памятью. Этот метод позволяет нескольким процессам совместно использовать одну и ту же страницу памяти до тех пор, пока данные не нужно будет изменить, что экономит ресурсы и ускоряет выполнение программ.
**Как работает Copy-on-Write:**
- **Совместное использование страниц:** Когда [[Процесс ОС|процесс]] создаёт копию себя (например, при вызове fork() в UNIX-подобных системах), операционная система не копирует все [[Страница|страницы]] памяти сразу. Вместо этого родительский и дочерний процессы продолжают совместно использовать одни и те же страницы памяти.

View File

@ -0,0 +1,27 @@
---
aliases:
- Многопоточность
- многопоточности
tags:
- maturity/🌱
date: 2024-10-08
zero-link:
parents:
linked:
---
**Многопоточность** — это одна из форм реализации [[Concurrency|конкурентности]], где задачи исполняются в виде отдельных [[Поток процесса ОС|потоков]] (threads) в рамках одного процесса.
Потоки могут выполняться параллельно ([[Parallelism]]) (если система многопроцессорная или многоядерная) или чередоваться на одном процессорном ядре, если ядер меньше, чем потоков. Потоки в одном процессе разделяют общие ресурсы, такие как память, что делает многопоточность эффективной для задач, где требуется обмен данными между потоками.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-08]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -1,17 +1,19 @@
---
aliases:
- параллелизм
- параллельно
tags:
- maturity/🌱
date: 2024-09-10
zero-link:
parents:
linked:
- "[[Concurrency]]"
---
Parallelism - система [[Concurrency|конкурентна]], но один или несколько блоков могут выполняться параллельно
Параллелизм это один из методов реализации [[Concurrency|конкурентности]]. Он предполагает ==выполнение нескольких задач одновременно, каждая из которых выполняется на отдельном процессорном ядре.== Это достигается на многоядерных системах, где каждое [[Ядро процессора|ядро]] может работать над своей задачей. Например, если у вас четыре ядра и четыре задачи, каждое ядро будет выполнять свою задачу параллельно, ускоряя процесс выполнения.
![[../../meta/files/images/Pasted image 20240910132902.png]]
[[Закон Амдала]]. Если значительная часть задачи выполняется последовательно, то добавление процессоров мало повлияет на ускорение.
![[../../meta/files/images/Pasted image 20241008204058.png]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]

View File

@ -0,0 +1,25 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-08
zero-link:
parents:
linked:
---
Асинхронность позволяет задачам выполняться в фоновом режиме, не блокируя основной поток программы. В синхронных операциях задача должна завершиться, прежде чем начнётся следующая, тогда как асинхронные задачи могут выполняться независимо, что особенно полезно для [[../architecture/Блокирующий вызов|блокирующих операций]].
Асинхронное программирование делает программы более отзывчивыми, позволяя основному потоку продолжать выполнение других задач, пока асинхронная операция выполняется. После завершения такой операции программа может вернуться к её результатам. В Java для этого используется класс `CompletableFuture`.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**:: [[Concurrency]]
**Источник**::
**Создана**:: [[2024-10-08]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,56 @@
---
aliases:
- блокировок
- блокировки
tags:
- maturity/🌱
date:
- - 2024-05-24
zero-link: []
parents:
linked:
---
Блокировки в разработке, особенно в контексте [[Multithreading|многопоточности]] и баз данных, относятся к механизмам, предотвращающим одновременный доступ к ресурсу несколькими [[Поток процесса ОС|потоками]] или [[Процесс ОС|процессами]], чтобы избежать несогласованности данных или других конфликтов.
**Минусы блокировок:**
- Есть риск получить [Deadlock](Deadlock.md)
- Блокировок может быть много
**Классификация:**
- По области действия.
- Строчные. Блокировка конкретной строки
- Гранулярные
- Предикативные
- По строгости
- Совместная. Shared lock. Можно читать заблокированные данные
- Исключительная. Exclusive lock. С заблокированными данными ничего делать нельзя.
**Виды реализаций:**
- **Мьютекс (Mutex)**:
- **Назначение**: Обеспечивают эксклюзивный доступ к ресурсу. Когда поток захватывает мьютекс, другие потоки должны ждать, пока он освободится.
- **Применение**: В многопоточных приложениях для синхронизации доступа к общим данным.
- **Читательские/писательские блокировки (Reader/Writer Locks)**:
- **Назначение**: Позволяют нескольким потокам читать ресурс одновременно, но блокируют доступ на запись. Если один поток пишет, все остальные потоки (и читатели, и писатели) должны ждать.
- **Применение**: Когда ресурс чаще читается, чем пишется, для улучшения производительности.
- **Семафоры (Semaphores)**:
- **Назначение**: Управляют доступом к ресурсу, ограничивая количество потоков, которые могут одновременно им пользоваться.
- **Применение**: Для ограничения количества одновременно выполняемых операций, например, подключения к базе данных.
- **Блокировки баз данных (Database Locks)**:
- **Назначение**: Предотвращают конкурентное выполнение операций, которые могут привести к некорректному состоянию данных.
- **Применение**: В системах управления базами данных (СУБД) для управления транзакциями и поддержания целостности данных.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Автор**::
**Создана**:: [[2024-05-24]]
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Two Phase Lock]]
<!-- SerializedQuery END -->

View File

@ -2,15 +2,16 @@
aliases:
- вытесняющей многозадачности
- вытесняющей многозадачностью
- Preemptive Multitasking
parents:
- "[[Многозадачность ЦПУ]]"
- "[[Многозадачность]]"
date: 2024-01-28
zero-link:
- "[[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]"
linked:
- "[[Кооперативная многозадачность]]"
---
Вытесняющая многозадачность — это подход к [[Многозадачность ЦПУ|многозадачности]], при котором [операционная система](Операционная%20система.md) имеет полный контроль над тем, когда и какой [процесс](Процесс%20ОС.md) или [поток](Поток%20процесса%20ОС.md) получает доступ к [[Центральный процессор|процессору]].
Вытесняющая многозадачность — это подход к [[Многозадачность|многозадачности]], при котором [операционная система](Операционная%20система.md) имеет полный контроль над тем, когда и какой [процесс](Процесс%20ОС.md) или [поток](Поток%20процесса%20ОС.md) получает доступ к [[Центральный процессор|процессору]].
[[Квантирование времени]]. Операционная система может прервать (вытеснить) текущий процесс или поток в любой момент времени, чтобы передать управление другому процессу или потоку, обеспечивая таким образом более эффективное и справедливое распределение процессорного времени между всеми выполняющимися задачами.
@ -18,7 +19,7 @@ linked:
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]
**Родитель**:: [[Многозадачность ЦПУ]]
**Родитель**:: [[Многозадачность]]
**Источник**::
**Автор**::
**Создана**:: [[2023-01-28]]

View File

@ -0,0 +1,32 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-08
zero-link:
parents:
linked:
---
Закон Амдала описывает ограничение на ускорение выполнения задачи при добавлении дополнительных процессоров или ресурсов в многопроцессорные системы. Он был предложен [[../../meta/people/Джин Амдал|Джином Амдалом]] в [[../../meta/date/year/1967|1967]] году и формулирует, что прирост производительности зависит от доли задачи, которая может быть выполнена [[Parallelism|параллельно]]. Если значительная часть задачи выполняется последовательно, то добавление процессоров мало повлияет на ускорение.
![[../../meta/files/images/Pasted image 20241008215741.png]]
Закон можно выразить математически: , где:
- S — ускорение выполнения программы,
- P — доля программы, которая может быть выполнена параллельно,
- N — количество процессоров.
При увеличении числа процессоров  ускорение  достигает предела, который зависит от последовательной части задачи. Если параллельная часть составляет 95%, то максимально достижимое ускорение будет ограничено в 20 раз, даже если будут доступны бесконечные вычислительные ресурсы. Это демонстрирует ключевое ограничение параллельных вычислений: ==последовательные компоненты задачи являются узким местом, которое ограничивает прирост производительности.==
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-08]]
**Автор**:: [[../../meta/people/Джин Амдал|Джин Амдал]]
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -14,7 +14,7 @@ date:
zero-link:
- "[[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]"
parents:
- "[[Многозадачность ЦПУ]]"
- "[[Многозадачность]]"
linked:
- "[[Вытесняющая многозадачность]]"
---
@ -34,7 +34,7 @@ linked:
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]
**Родитель**:: [[Многозадачность ЦПУ]]
**Родитель**:: [[Многозадачность]]
**Источник**::
**Автор**::
**Создана**:: [[2024-03-19]]

View File

@ -1,6 +1,8 @@
---
aliases:
- многозадачности
- Многозадачность ЦПУ
- Multitasking
tags:
- maturity/🌱
date:
@ -13,13 +15,16 @@ linked:
---
Многозадачность — это способность [операционной системы](Операционная%20система.md) одновременно управлять выполнением нескольких задач ([процессов](Процесс%20ОС.md) или [потоков](Поток%20процесса%20ОС.md)). Это достигается путем распределения [[Планировщик ОС|планировщиком ОС]] доступного процессорного времени между различными задачами таким образом, чтобы создать иллюзию их параллельного выполнения. Многозадачность может быть реализована в двух основных формах: кооперативной и вытесняющей.
- [[Переключение контекста]]. Механизм, который позволяет операционной системе сохранять и загружать состояние (контекст) процессов или потоков. Это ключевой компонент, обеспечивающий многозадачность, так как без него невозможно было бы переключаться между задачами.
- [[Кооперативная многозадачность]] требует, чтобы каждая задача явно отдавала управление операционной системе, чтобы другие задачи могли выполняться. Этот подход может привести к проблемам, если задача не отдает управление.
- [[Вытесняющая многозадачность]] позволяет операционной системе "вытеснять" текущую задачу и переключаться на другую задачу, обеспечивая более надежный и справедливый механизм планирования. Этот подход наиболее распространен в современных операционных системах.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]
**Родитель**:: [[Центральный процессор|ЦПУ]]
**Родитель**:: [[Центральный процессор|ЦПУ]], [[Concurrency]]
**Источник**::
**Автор**::
**Создана**:: [[2024-01-28]]
@ -28,6 +33,7 @@ linked:
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Concurrency]]
- [[Вытесняющая многозадачность]]
- [[Кооперативная многозадачность]]
- [[Переключение контекста]]

View File

@ -15,8 +15,8 @@ date:
zero-link:
- "[[../../meta/zero/00 Разработка|00 Разработка]]"
parents:
- "[[Многозадачность ЦПУ]]"
linked:
- "[[Многозадачность]]"
linked:
---
Переключение контекстов происходит, когда [[../../../../knowledge/dev/pc/Операционная система|операционная система]] останавливает выполнение одной задачи и начинает выполнение другой ([[Concurrency|Concurrency]]). Этот процесс включает в себя сохранение текущего состояния задачи (контекста), включая значения регистров процессора, указатель инструкций и другие связанные с задачей данные, чтобы впоследствии можно было возобновить выполнение задачи с того места, где она была остановлена.
@ -45,7 +45,7 @@ linked:
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**:: [[Многозадачность ЦПУ|Многозадачность ЦПУ]]
**Родитель**:: [[Многозадачность|Многозадачность ЦПУ]]
**Источник**::
**Автор**::
**Создана**:: [[2024-01-28]]

View File

@ -10,6 +10,7 @@ aliases:
- потоку
- потоком ОС
- потоку ОС
- потоками
tags:
- maturity/🌱
date: 2024-01-28

View File

@ -42,6 +42,6 @@ linked:
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Многозадачность ЦПУ]]
- [[Ядро процессора]]
- [[Многозадачность]]
<!-- SerializedQuery END -->

View File

@ -26,7 +26,7 @@ linked:
- **Энергопотребление и производительность**: Современные ЦП обычно включают в себя функции для оптимизации энергопотребления и производительности, такие как динамическое изменение частоты и напряжения в зависимости от нагрузки.
- **Специализированные ядра**: Некоторые процессоры включают специализированные ядра для конкретных задач, например, графические ядра в CPU с интегрированной графикой или ядра, оптимизированные для искусственного интеллекта и машинного обучения.
==В любой конкретный момент времени одно ядро процессора может выполнять инструкции только одного [потока](Поток%20процесса%20ОС.md).== Благодаря [[Планировщик ОС|планировщику ОС]] создается иллюзия того, что множество потоков выполняются параллельно, хотя на самом деле они выполняются последовательно, но с очень высокой скоростью переключения, - [[Многозадачность ЦПУ]]
==В любой конкретный момент времени одно ядро процессора может выполнять инструкции только одного [потока](Поток%20процесса%20ОС.md).== Благодаря [[Планировщик ОС|планировщику ОС]] создается иллюзия того, что множество потоков выполняются параллельно, хотя на самом деле они выполняются последовательно, но с очень высокой скоростью переключения, - [[Многозадачность]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ЭВМ|00 Архитектура ЭВМ]]

142
dev/java/synchronized.md Normal file
View File

@ -0,0 +1,142 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-09
zero-link:
parents:
linked:
---
synchronized — это один из ключевых механизмов в Java для управления [[Многопоточность в Java|многопоточностью]] и обеспечения безопасности при доступе к разделяемым ресурсам. Этот модификатор используется для того, чтобы ограничить доступ к критическим секциям кода, тем самым предотвращая состояния гонки ([[../other/Race condition|race conditions]]).
**Как работает synchronized**
Synchronized может применяться к методам или блокам кода. Когда поток входит в метод или блок, помеченный `synchronized`, он получает [[Монитор в Java|монитор]] (lock) на объект, связанный с этим кодом. Другие потоки не могут получить доступ к этому коду до тех пор, пока монитор не будет освобожден. Это гарантирует, что только один поток может одновременно выполнять данный код.
В этом примере, `synchronized` гарантирует, что методы `increment` и `getCount` не будут выполняться одновременно несколькими потоками, предотвращая некорректные обновления переменной `count`.
```java
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
```
Иногда удобнее синхронизировать не весь метод, а только его часть. В этом случае можно использовать блок `synchronized`:
```java
public void increment() {
synchronized (this) {
count++;
}
}
```
**Особенности**
- **Мониторы привязаны к объектам**, а не к методам. Если вы синхронизируете метод экземпляра (instance method), то монитором является текущий объект (this). Если метод статический, то монитором выступает сам класс (ClassName.class).
- **Блокировки могут привести к взаимной блокировке** ([[../../../../_inbox/Deadlock|deadlock]]), если два потока пытаются захватить друг у друга мониторы в неправильном порядке.
**Ограничения**
- **Синхронизация снижает производительность**, так как потоки вынуждены ожидать освобождения блокировки.
- **Недостаточная гибкость:** при сложных задачах многопоточности использование `synchronized` может стать неэффективным, и тогда лучше рассмотреть более современные и гибкие альтернативы, такие как классы из пакета `java.util.concurrent` (например, `ReentrantLock`).
## Частые проблемы и ошибки
### Чрезмерная синхронизация (Over-synchronization)
**Проблема:** Синхронизация всего метода или слишком большого объема кода может снизить производительность программы, так как потоки вынуждены ждать доступа к синхронизированным участкам, даже если это не требуется.
**Решение:** Следует синхронизировать только ту часть кода, которая действительно требует защиты.
### Синхронизация на неправильном объекте
**Проблема:** Если синхронизация происходит на локальном или временном объекте, это не защитит данные, так как каждый поток будет работать с собственной копией объекта.
```java
public class Counter {
private int count = 0;
public void increment() {
// Неправильная синхронизация на локальном объекте
Object lock = new Object();
synchronized (lock) {
count++;
}
}
}
```
Здесь каждый поток создает собственный объект `lock`, и, следовательно, синхронизация не работает.
**Решение:** Синхронизацию нужно выполнять на общем объекте (например, `this` или другом общем объекте).
### Синхронизация на статических и нестатических методах
**Проблема:** Если не понимать, как работают мониторы для статических и нестатических методов, можно случайно создать ситуацию, когда доступ к объектам будет синхронизирован некорректно.
```java
public class StaticSyncExample {
private static int staticCount = 0;
private int instanceCount = 0;
public static synchronized void incrementStatic() {
staticCount++;
}
public synchronized void incrementInstance() {
instanceCount++;
}
}
```
Здесь вызов `incrementStatic` синхронизируется на классе `StaticSyncExample.class`, а `incrementInstance` — на конкретном объекте класса. Это может привести к недоразумениям в случаях, когда ожидается один и тот же монитор для всего кода.
Еще один пример
```java
public class Container {
private static final List<String> list = new ArrayList<>();
synchronized void addEntry(String s) {
list.add(s)
}
}
```
Здесь у нас будет проблема, если будет 2+ объекта класса `Container`, так как каждый из них будет синхронизироваться на своем объекте, а переменная `list` у нас статическая и ее экземпляр единственный на всю программу
**Решение:** Нужно учитывать, что статические и нестатические методы используют разные мониторы. Чтобы синхронизировать весь класс (включая как статические, так и нестатические данные), можно использовать общий объект для синхронизации.
### Пропуск синхронизации для чтения и записи
**Проблема:** Разрешение чтения переменных без синхронизации, тогда как их запись синхронизирована, может привести к непредсказуемым результатам, поскольку значения могут быть прочитаны в неконсистентном состоянии.
```java
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
// Неправильное чтение без синхронизации
public int getCount() {
return count;
}
}
```
В этом случае разные потоки могут получить некорректное значение переменной count.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]]
**Родитель**:: [[Многопоточность в Java]]
**Источник**::
**Создана**:: [[2024-10-09]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,26 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-08
zero-link:
parents:
linked:
---
- [[synchronized]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-08]]
**Автор**::
### Дополнительные материалы
- [[../../source/lecture/Доклад. Лекция 11. Многопоточность в Java|Доклад. Лекция 11. Многопоточность в Java]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[synchronized]]
<!-- SerializedQuery END -->

View File

@ -2,6 +2,8 @@
aliases:
- состояние гонки
- условие гонки
- состояния гонки
- race conditions
tags:
- maturity/🌱
date:
@ -10,6 +12,10 @@ zero-link:
parents:
linked:
---
Состояние гонки возникает, когда два или более потока одновременно пытаются получить доступ к одному и тому же ресурсу (например, переменной), причём хотя бы один поток изменяет его значение. В таких случаях порядок выполнения потоков не гарантирован, что приводит к непредсказуемому поведению программы. Например, один поток может записывать данные, в то время как другой — читать, что вызывает некорректные результаты.
Для предотвращения состояния гонки применяются механизмы синхронизации, такие как мьютексы, блокировки или ключевое слово synchronized в Java. Эти средства гарантируют, что только один поток может изменять общий ресурс в любой момент времени.
Пример race condition в БД:
![](../../meta/files/images/Pasted%20image%2020240619200549.png)
***

View File

@ -0,0 +1,9 @@
## Заметки созданные в этот день
<!-- QueryToSerialize: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
<!-- SerializedQuery: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
- [[Кэширование]]
- [[Least Recently Used]]
- [[Принцип локальности]]
- [[Блокировка]]
<!-- SerializedQuery END -->

View File

@ -0,0 +1,13 @@
## Заметки созданные в этот день
<!-- QueryToSerialize: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
<!-- SerializedQuery: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
- [[Томас Эдисон]]
- [[Сергей Петрелевич]]
- [[Т-Банк]]
- [[Один клиент — один поток]]
- [[Много клиентов — один поток]]
- [[Версионирование ПО]]
- [[Семантическое версионирование]]
- [[Доклад. Могут ли Virtual threads заменить Webflux]]
- [[Конференция. JVM Day 2024]]
<!-- SerializedQuery END -->

View File

@ -0,0 +1,7 @@
## Заметки созданные в этот день
<!-- QueryToSerialize: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
<!-- SerializedQuery: LIST WHERE "garden/ru" and (contains(date, this.file.link) or contains(Создана, this.file.link)) -->
- [[Закон универсальной масштабируемости]]
- [[Нил Гюнтер]]
<!-- SerializedQuery END -->

5
meta/date/year/1879.md Normal file
View File

@ -0,0 +1,5 @@
<!-- QueryToSerialize: LIST FROM [[]] -->
<!-- SerializedQuery: LIST FROM [[]] -->
- [[Супрахиазматическое ядро]]
<!-- SerializedQuery END -->

0
meta/date/year/1967.md Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -0,0 +1 @@
109507cc7b8aa5b18b603ac4544d8b5a

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
dbc5acee876c6ccd321904c22a607557

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

View File

@ -0,0 +1 @@
968703a8a5dcdfaf965649c5b7ba36bf

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

View File

@ -0,0 +1 @@
6db9029edf2c9c3a10bc373f742c07ae

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1 @@
109507cc7b8aa5b18b603ac4544d8b5a

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
dbc5acee876c6ccd321904c22a607557

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1 @@
968703a8a5dcdfaf965649c5b7ba36bf

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -0,0 +1 @@
6db9029edf2c9c3a10bc373f742c07ae

View File

@ -0,0 +1,13 @@
---
tags:
- type/people
date: 2024-10-09
aliases:
- Джином Амдалом
---
**Work**::
**Position**::
**Создана**:: [[2024-10-09]]
**Telegram**::
## Упоминается в заметках
<!-- QueryToSerialize: LIST FROM [[]] -->

View File

@ -0,0 +1,16 @@
---
tags:
- type/people
date: 2024-10-09
aliases:
- Нилом Гюнтером
---
**Work**::
**Position**::
**Создана**:: [[2024-10-09]]
**Telegram**::
## Упоминается в заметках
<!-- QueryToSerialize: LIST FROM [[]] -->
<!-- SerializedQuery: LIST FROM [[]] -->
- [[2024-10-09]]
<!-- SerializedQuery END -->

View File

@ -3,12 +3,12 @@ tags:
- type/zero-link
zero-link:
- "[[00 Разработка]]"
permalink: dev/java
title: Java разработка
---
- [Устройство Java](Устройство%20Java.md)
- [JDK](../../dev/java/JDK.md)
- [[../../dev/java/Java Reflection|Java Reflection]]
- [[../../dev/java/Многопоточность в Java|Многопоточность в Java]]
- Системы сборки
- [Maven](00%20Maven.md)
- [[00 Gradle|Gradle]]
@ -19,6 +19,19 @@ title: Java разработка
- [Hibernate](00%20Hibernate.md)
- [[../../../../knowledge/dev/java/other/Jackson|Jackson]]
- [Снипеты для Java](00%20Снипеты%20для%20Java.md)
## Мои образовательные статьи
- [Функциональные интерфейсы и лямбды в Java](https://struchkov.dev/blog/ru/lambda-expression-java/)
- [Основы памяти в Java: Куча и Стек](https://struchkov.dev/blog/ru/memory-in-java/)
- [Глубокое погружение в Stream API Java: Понимание и Применение](https://struchkov.dev/blog/ru/java-stream-api/)
- [Реактивное программирование на Java. Будущее, настоящее и прошлое](https://struchkov.dev/blog/ru/overview-of-reactive-programming/)
- [Обзор всех модификаторов в Java](https://struchkov.dev/blog/ru/modifiers-in-java/)
- [Основы транзакций в Spring и JDBC](https://struchkov.dev/blog/ru/transaction-jdbc-and-spring-boot/)
- [Большой гайд по Optional в Java](https://struchkov.dev/blog/ru/optional-in-java/)
- [Java Collection Framework: Полное руководство для разработчиков](https://struchkov.dev/blog/ru/java-collection-framework/)
- [Аннотации в Java. Как создать свою аннотацию](https://struchkov.dev/blog/ru/creating-annotation-java/)
- [Публикация Java приложения в личный Nexus](https://struchkov.dev/blog/ru/java-jar-deploy-to-nexus/)
- [Публикация Java библиотеки в Maven Central](https://struchkov.dev/blog/ru/deploy-to-maven-central/)
## Мои рассуждения
- [Использование wildcard imports в Java](../../dev/java/Использование%20wildcard%20imports%20в%20Java.md)
- [Сравнение константы слева в Java](../../dev/java/Сравнение%20константы%20слева%20в%20Java.md)

View File

@ -5,6 +5,6 @@ title: Архитектура ЭВМ
---
- [Центральный процессор](../../dev/fundamental/Центральный%20процессор.md)
- [[../../dev/fundamental/Ядро процессора|Ядро процессора]]
- [[../../dev/fundamental/Многозадачность ЦПУ|Многозадачность ЦПУ]]
- [[../../dev/fundamental/Многозадачность|Многозадачность ЦПУ]]
- [Планировщик ОС](../../dev/fundamental/Планировщик%20ОС.md)
- [Оперативная память](Оперативная%20память.md)