Литература и документация

  1. Java Concurrency in Practice (By Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bow beer, David Holmes, Doug Lea) - https://pdfs.semanticscholar.org/3650/4bc31d3b2c5c00e5bfee28ffc5d403cc8edd.pdf
  2. Пакет java.util.concurrent.
    1. Java docs: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html.
    2. Хорошее описание в статье https://habr.com/ru/company/luxoft/blog/157273/

Порядок изучения

Предполагается следющий порядок изучения:

  1. В Java Concurrency in Practice изучить часть I
  2. Решить задачи по коллекциям
  3. Изучение частей II и III из Java Concurrency in Practice поможет в решении задачи Шагающий экскаватор
  4. Далее можно обратить внимание на инструментарий из пакета java.util.concurrent.
  5. Решить задачу Управление счетами, потребуется обратиться к части IV книги Java Concurrency in Practice
  6. Далее можно попробовать решить задачу на Highload

Практика

Коллекции

  1. Реализовать потокобезопасную очередь блокировки реализующей интерфейс Queue (https://www.geeksforgeeks.org/blockingqueue-interface-in-java/)
    1. с использованием wait\notify
    2. с использованием интерфейса Lock
    3. свой вариант
  2. Реализовать потокобезопасный List с неблокирующим чтением и блокирующим изменением, то есть доступ к элементам коллекции блокируется если какой-то поток изменяет коллекцию (добавляет, меняет или удаляет элементы), иначе все потоки имеют доступ к элементам коллекции одновременно. 
    1. c wait\notify
    2. c использованием интерфейса Lock
    3. c использованием ReadWriteLock
    4. свой вариант

Синхронизация потоков

Управление счетами

ВариантОписание
1-й

Счет - сущность с двумя атрибутами

  1. Идентификатор счета - int
  2. Количество средств - double

Транзакция или перевод - это перевод средств между счетами. Транзакция имеет три атрибута: сумма перевода, идентификатор счета с которого снимаются деньги, идентификатор счета, на который переводятся средства. Транзакция атомарна. Другие потоки не должны иметь доступа к счетам транзакции в момент выполнения транзакции. 

Задание:

  1. Есть множество счетов. Счета инициализируются случайным образом при старте программы.
  2. Есть пул из N потоков (количество потоков можно задавать) выполняющих транзакции. Детали транзакции поток забирает из очереди транзакций на обработку. Если очередь пуста - потоки ждут пока там не появятся транзакции на обработку.
  3. В отдельном потоке генератор транзакций раз в случайное количество миллисекунд создает транзакцию и добавляет в очередь для обработки.
  4. Есть информационный поток, который раз в 10 секунд суммирует средства на всех на всех счетах и распечатывает результат в консоль. Очевидно, что сумма не должна меняться. Также распечатывается количество обработанных транзакций и количество транзакций в очереди на обработку.


2-й

К 1-му варианту добавим:

  1. Начинаем брать комиссию за транзакцию, То есть нужно создать выделенный счет для комиссии, на который каждый поток при выполнении транзакции сбрасывает к примеру 0.5% суммы перевода, остальные 99.5% суммы переводим между целевыми счетами. 
  2. Информационный поток раз в 10 секунд распечатывает сумму средств на всех счетах и отдельно количество средств на выделенном счету для комиссии.
  3. Скорость работы не должна измениться.


3-й

Меняем программу из варианта 1 или 2 таким образом, чтобы появлялись взаимные блокировки.

Информационный поток должен дополнительно распечатывать взаимно заблокированные транзакции.


Шагающий экскаватор

Решения использующие Thread.sleep не рассматриваются.

ВариантОписание
Взаимодействие 2-х потоков

1-й поток распечатывает свое имя и номер шага в консоль и передает поток управления 2-му потоку.

2-й поток распечатывает свое имя и номер шага в консоль и передает поток управления  обратно.

Для номера шага возможны варианты

  1. Каждый поток ведет свой собственный счетчик шагов
  2. Используется сквозной счетчик, один на все потоки
Взаимодействие N потоковКоличество потоков параметризировано, то есть можно задать количество потоков, которые распечатывают шаги и передают поток управления следующему потоку, Последний поток передает поток управления 1-му. Шаги вычисляются также как и в первом варианте.
Рандомизированный вариант

Реализовать сервис, который возвращает номер следующего потока (например статический метод, возвращающий случайное число)

Условия такие же как и в варианте 2, только работающий поток дополнительно запрашивает номер следующего потока и передает управление ему.

Highload 

Ticks calculation

  1. 10.000-100.000 инструментов
  2. 50-500 индексов по 200 инструментов с весами
  3. 10.000 котировок в секунду
  4. Раз в секунду нужно рассчитывать значения индексов и сохранять слепок цен инструментов и значений индексов на данную секунду.
  5. Задержка обработки котировки не более секунды, т.е. котировка пришедшая позже секунды N должна попасть в слепок N+1
  6. Приложение должно проработать хотябы 1 час

Можно попробовать специфические вещи типа Disruptor или внешние кэши типа Hazelcast или Ehcache, но скорее всего не поможет.

  • Нет меток