Многопоточность в Java – Все, что Вам НУЖНО Знать

Когда мы запускаем приложение в реальном мире, мы используем хорошие процессоры для более быстрого выполнения. Но только скорость процессора не может сделать ваше приложение быстрым. Один из отличных способов создать эффективное с точки зрения производительности приложение – использовать многозадачность.

Что такое многозадачность?

Многозадачность – это концепция программирования, при которой приложение может создавать небольшие задачи для выполнения параллельно. Если вы работаете на компьютере, он запускает несколько приложений и выделяет для них вычислительную мощность. Простая программа выполняется последовательно, и операторы кода выполняются один за другим. Это однопоточное приложение. Но если язык программирования поддерживает создание нескольких потоков и передачу их операционной системе для параллельного выполнения, это называется многозадачностью.

Многозадачность против многозадачности

Когда речь идет о многозадачности, нам не важно, имеет ли машина 2-ядерный процессор или 16-ядерный процессор. Наша задача – создать многозадачное приложение и позволить операционной системе управлять выделением и выполнением. Коротко говоря, многозадачность не имеет ничего общего с многозадачностью.

Как Java поддерживает многопоточность?

Java обладает отличной поддержкой многопоточных приложений. Java поддерживает многопоточность через класс Thread. Поток Java позволяет нам создавать легкие процессы, которые выполняют определенные задачи. Мы можем создавать несколько потоков в нашей программе и запускать их. Среда выполнения Java заботится о создании машинных инструкций и взаимодействии с операционной системой для их параллельного выполнения.

Какие существуют типы потоков?

В приложении существуют два типа потоков – пользовательский поток и демон-поток. Когда мы запускаем приложение, первый поток, созданный, является пользовательским, это main. Мы можем создавать как пользовательские потоки, так и демон-потоки. Когда все пользовательские потоки завершены, JVM завершает программу.

Что такое приоритет потока?

При создании потока мы можем задать его приоритет. Мы можем устанавливать разные приоритеты для разных потоков, но это не гарантирует, что поток с более высоким приоритетом будет выполняться раньше потока с более низким приоритетом. Планировщик потоков является частью реализации операционной системы, и когда поток запускается, его выполнение контролируется планировщиком потоков, и JVM не имеет никакого контроля над его выполнением.

Как создать поток в Java?

Мы можем создавать потоки, реализуя интерфейс Runnable или расширяя класс Thread.

Thread t = new Thread(new Runnable(){
    @Override
    public void run() {
    }
});

Выше приведен однострочный код для создания нового потока. Здесь мы создаем объект Runnable в виде анонимного класса. Если вы знакомы с лямбда-выражениями, мы можем создать поток с гораздо более коротким кодом.

Runnable runnable = () -> System.out.println("Hello");

После создания потока мы должны запустить его выполнение, вызвав метод start().

runnable.start();

I have written a lot of posts explaining the concepts of multithreading in Java. You can go through these in sequence to learn everything about multithreading, its real-life usage, thread lifecycle, thread pool, etc.

1. Java Thread и Runnable

Это первый пост о классе Thread и интерфейсе Runnable. Вы также узнаете о процессе и потоке. В чем разница между потоком и процессом? Преимущества использования потоков и как мы можем создавать потоки с использованием интерфейса Runnable и класса Thread. Этот пост также сравнивает интерфейс Runnable с классом Thread.

2. Java Thread Sleep

Java Thread sleep используется для приостановки выполнения текущего потока. Мы будем часто использовать Thread sleep в будущих сообщениях, поэтому полезно знать, как это работает и точно ли оно?

3. Java Thread Join

Иногда нам нужно подождать, пока другие потоки завершат свое выполнение, прежде чем мы сможем продолжить. Мы можем достичь этого, используя метод join потока, узнайте, как это работает и когда мы должны его использовать.

4. Состояния потоков Java

Понимание различных состояний потока важно. Узнайте, как поток изменяет свое состояние, и как планировщик потоков операционной системы изменяет состояние потока.

5. Ожидание, уведомление и notifyAll в потоках Java

Класс Java Object содержит три метода для обмена состоянием блокировки ресурса. Изучите пример использования этих методов класса Object в простой реализации ожидания-уведомления.

6. Потокобезопасность и синхронизация

Мы знаем, что потоки делят ресурсы объектов, что может привести к искажению данных, потому что эти операции не являются атомарными. Узнайте, как мы можем обеспечить безопасность потоков в Java, используя различные методы. Прочитайте этот пост, чтобы узнать о правильном использовании синхронизации, синхронизированных методов и блоков синхронизации.

7. Java Исключение в потоке main

Виртуальная машина Java создает первый поток с помощью метода main. В этом посте объясняются некоторые распространенные исключения, с которыми мы сталкиваемся в повседневной жизни, и их корень проблемы, а также способы их устранения.

8. Потокобезопасность в классе Singleton

В этой статье вы узнаете основные концепции создания класса Singleton. Какие проблемы с потокобезопасностью возникают при различных реализациях? Как мы можем достичь потокобезопасности в классе Singleton.

9. Демонический поток в Java

A simple article explaining daemon threads and how we can create daemon threads in java.

10. Локальный поток Java

Мы знаем, что потоки делят переменные объекта, но что если мы хотим иметь переменные, привязанные к потоку, созданные на уровне класса? В Java есть утилитный класс ThreadLocal для создания таких переменных, прочтите далее, чтобы узнать, как мы можем создавать переменные ThreadLocal в программе на Java.

11. Java Thread Dump

Дамп потока Java предоставляет информацию о текущем потоке. Дамп потока полезен для анализа проблем производительности приложения. Вы можете использовать дамп потока для выявления и устранения ситуаций взаимной блокировки. В этом посте объясняются различные методы создания дампов потоков в Java.

12. Как анализировать взаимную блокировку в Java

Дедлок – это ситуация, когда несколько потоков ожидают друг друга для освобождения ресурсов, вызывая циклическую зависимость. В данной статье обсуждается ситуация, в которой мы можем столкнуться с дедлоком в программе на языке Java. Как мы можем использовать выгрузку потоков для обнаружения дедлока и лучшие практики по предотвращению дедлока в программе на Java.

13. Потоковый таймер Java

В этой статье объясняется, как мы можем использовать классы Java Timer и TimerTask для создания задач, выполняющихся с интервалом по расписанию. Приведен пример программы, демонстрирующий его использование, и рассказано, как мы можем отменить таймер.

14. Проблема производителя и потребителя на Java

До появления Java 5 проблему производителя и потребителя можно было решить, используя методы wait() и notify(). Однако введение BlockingQueue сделало это очень простым. Узнайте, как мы можем использовать BlockingQueue для решения проблемы производителя и потребителя на Java.

15. Пул потоков Java

Пул потоков Java – это набор рабочих потоков, ожидающих обработки заданий. В Java 5 введение фреймворка Executor значительно упростило создание пула потоков в Java. Мы можем использовать классы Executors и ThreadPoolExecutor для создания и управления пулом потоков.

16. Вызываемое будущее Java

Иногда нам нужно, чтобы наш поток возвращал некоторые значения, которые мы можем использовать. В Java 5 для этого можно использовать Callable, который аналогичен интерфейсу Runnable. Мы можем использовать фреймворк Executor для выполнения задач Callable.

17. Пример Java FutureTask

Класс FutureTask является базовым конкретным классом, который реализует интерфейс Future. Мы используем его с реализацией Callable и Executors для асинхронной обработки. Класс FutureTask предоставляет методы реализации для проверки состояния задачи и возврата значения программе вызывающего, как только ее обработка завершена. Это пригодится, когда вы хотите переопределить некоторые из методов реализации интерфейса Future.

Вывод

Многопоточность – очень обширная тема, и написать о ней все в одном посте было бы невозможно. Если вы прочитаете вышеизложенные посты последовательно, вы узнаете все о многопоточности в Java.

Source:
https://www.digitalocean.com/community/tutorials/multithreading-in-java