Ответ
Многопоточность в Java — это выполнение нескольких потоков (threads) внутри одного процесса для параллельной или конкурентной обработки задач.
1. Создание и запуск потока:
- Через
Runnable(предпочтительнее):Runnable task = () -> { System.out.println("Выполняется в потоке: " + Thread.currentThread().getName()); }; Thread thread = new Thread(task); thread.start(); // Важно: start(), а не run() - Через наследование
Thread:class MyThread extends Thread { @Override public void run() { /* логика */ } } new MyThread().start();
2. Синхронизация и безопасность потоков:
-
Ключевое слово
synchronized:public synchronized void method() { /* ... */ } // Синхронизация по экземпляру (this) synchronized (lockObject) { // Синхронизация по произвольному объекту // критическая секция } - Использование атомарных классов (
java.util.concurrent.atomic):AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet(); // Атомарная операция - Ключевое слово
volatile: Гарантирует видимость изменений переменной для всех потоков (но не атомарность составных операций).
3. Управление пулами потоков (ExecutorService):
ExecutorService executor = Executors.newFixedThreadPool(4); // Пул из 4 потоков
for (int i = 0; i < 10; i++) {
executor.submit(() -> System.out.println("Task " + i));
}
executor.shutdown(); // Остановка после выполнения всех задач
4. Потокобезопасные коллекции: Используйте их вместо ручной синхронизации.
ConcurrentHashMapCopyOnWriteArrayListBlockingQueue(например,ArrayBlockingQueue)
5. Распространённые проблемы:
- Состояние гонки (Race Condition): Несогласованный доступ к общим данным.
- Взаимная блокировка (Deadlock): Два или более потока бесконечно ждут друг друга.
- Голодание (Starvation): Поток не получает доступа к ресурсам.
Современный подход: Для асинхронных вычислений и композиции задач используйте CompletableFuture (Java 8+).