4 подписчика
Многопоточность за 100 слов
Проблема:
есть объект
запускаем два потока
у каждого потока свой кэш, то есть каждый поток создает копию этого объекта, а не работает с ним напрямую
дальше по шагам:
1) первый поток скопировал объект к себе в кэш
2) первый поток изменил поле объекта
3) второй поток скопировал объект к себе в кэш
4) второй поток изменяет это же поле (и не знает об изменениях, сделанных первым потоком!)
5) второй поток записывает изменения в общую память
6) первый поток записывает изменения в общую память
бац — мы потеряли изменения, сделанные во втором потоке. первый поток их перезаписал + второй поток даже не знал, что объект был изменен в первом потоке!
Как этого избежать:
• synchronized — запрещает нескольким потокам работать с объектом (классом) одновременно
перед тем как выполнить участок кода, поток захватывает объект (класс), а другие потоки ждут освобождения объекта (класса)
- synchronized(Object) — захватывает объект
- synchronized fun — можно читать как synchronized(this), захватывает объект
- static synchronized fun — захватывает класс (а не объект)
• volatile — синхронизирует чтение и запись
сработает, если один поток только читает, а другой только пишет
не сработает, если оба потока изменяют объект — потому что операции между чтением и записью не синхронизированы
• atomic
атомарная операция = неделимая операция изменения объекта
с объектами, имеющими атомарные операции изменения (например, увеличение на единицу для AtomicInteger), можно работать в разных потоках без ручной синхронизации
в Java есть атомарные примитивы, коллекции и класс AtomicReference для работы с произвольными классами
....
а нужно ли думать о синхронизации переменной в корутинах?
сработают ли там эти подходы?
1 минута
10 ноября 2022