Создать программу, обрабатывающую потоки задач, исполняемых сотрудниками в процессе работы, используя многопоточность.
- Рабочий день длится максимум 8 часов;
- Каждая задача длится от 1 часа до 16 часов (необходимо разбивать время потраченное на задачу на несколько дней);
- Необходимо рассчитывать время, затрачиваемое сотрудниками на исполнение своих задач, время простоя сотрудника, и время проведённое сотрудником на работе.
- Данные сотрудников и время их работы хранятся в xlsx файле;
- В конце рабочего дня информация сохраняется в xlsx файл;
- В конце рабочего дня собирается статистика по сотрудникам и их эффективности.
Придумать и реализовать практическую задачу, в которой необходимо использование многопоточности для ускорения времени выполнения работы (телеграм бот и т.д.).
Для начала необходимо разобраться с понятиями Поток и Процесс и как идёт исполнение программы в целом.
Процесс - это экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве.
Таким образом процессом называется ни что иное, как сама наша программа, которую мы разрабатываем, а она уже может разбиваться на разные потоки.
Поток - это определенный способ выполнения процесса. Когда один поток изменяет ресурс процесса, это изменение сразу же становится видно другим потокам этого процесса.
Самый известный нам поток - это главный поток main.
А ещё есть потоки "демоны".
Вообще, программа всегда завершает свою работу, как только отработали все потоки, после чего завершается процесс.
Но ведь нам не нужно чтобы всегда программа завершалась после того как закончатся все потоки. Для этого и служат потоки "демоны".
Их отличие заключается в том, что они могут завершиться до своего полного выполнения. То есть процесс завершится, даже если поток-демон ещё не закончил свою задачу.
Многопоточность - это форма параллельной обработки или разделения задач на части для одновременной обработки. Вместо отправки большой задачи на одно ядро, многопоточные программы разбивают задачи на несколько частей или потоков.
Когда нам нужно ускорить выполнение нашей программы. Например:
- Веб интерфейсы;
- Мессенджеры;
- Программы для сложных множественных вычислений;
- Для обработки больших данных.
В Java для этого служат класс Thread наследующий интерфейс Runnable, а также несколько вспомогательных, но об этом позже.
Класс Thread - это класс потока. Данный класс содержит практически все основные методы, которые нам понадобятся в большинстве случаев.
В первую очередь это start() - запускающий поток и run() - определяющий точку входа в поток, а ещё sleep() - приостанавливающий исполнение потока на определённое время в миллисекундах.
Также есть join() - для ожидания исполнения другого потока, isAlive() - возвращает состояние потока, yield() - заставляет переключиться на другой поток и многие другие.
В некоторых ситуациях у нас может возникнуть состояния:
- Deadlock (взаимная блокировка) - это состояние, когда несколько потоков находятся в состоянии ожидания ресурсов, занятых друг другом, и ни один из них не может продолжать выполнение.
- Race Condition (состояние гонки) - это ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода.
Как правило Deadlock возникает в Race Condition.
Для избегания таких ситуаций используются оператор synchronized или класс Semaphore, которые определяют последовательность выполнения и использования каких-либо методов, для избежания взаимной блокировки. А ещё есть мьютексы и мониторы.
Однако не стоит забывать, что Deadlock можно получить даже используя методы синхронизации потоков.
А также, что синхронизируя потоки мы фактически превращаем нашу многопоточную программу в фактически однопоточную, но иногда это необходимо.