Синхронизация потоков в Java
Синхронизация потоков
94
Конкурентное использование ресурсов в многопоточных приложениях может приводить к ошибкам, таким как гонки данных (race condition) и дедлоки (deadlock). Для того чтобы избежать этих ошибок, в Java существуют механизмы синхронизации потоков.
- Синхронизация метода
class Counter { private int count; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
В этом примере, методы increment
и getCount
синхронизированы, чтобы избежать гонки данных при многопоточном использовании объекта Counter
.
- Использование блока синхронизации
class Counter { private int count; public void increment() { synchronized(this) { count++; } } public int getCount() { synchronized(this) { return count; } } }
Здесь методы increment
и getCount
не синхронизированы, но блоки кода в них синхронизированы по объекту this
.
- Использование
Lock
-объекта
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Counter { private int count; private Lock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public int getCount() { lock.lock(); try { return count; } finally { lock.unlock(); } } }
Этот пример использует объект Lock
для синхронизации блоков кода. Метод increment
блокирует lock
, затем выполнение кода, затем разблокирует lock
. Аналогично для метода getCount
.
- Использование
synchronized
блока на статическом методе
class Counter { private static int count; public static synchronized void increment() { count++; } public static synchronized int getCount() { return count; } }
Здесь методы increment
и getCount
синхронизированы с помощью synchronized
на статическом методе класса Counter
. Это гарантирует, что только один поток будет иметь доступ к этим методам одновременно.
- Использование
Semaphore
import java.util.concurrent.Semaphore; class Counter { private int count; private Semaphore semaphore = new Semaphore(1); public void increment() throws InterruptedException { semaphore.acquire(); try { count++; } finally { semaphore.release(); } } public int getCount() throws InterruptedException { semaphore.acquire(); try { return count; } finally { semaphore.release(); } } }
В этом примере используется Semaphore
для ограничения доступа к методам increment
и getCount
только одному потоку одновременно. Semaphore инициализируется значением 1, что позволяет одному потоку захватывать семафор, в то время как остальные будут ждать. Когда поток освобождает семафор, следующий поток может захватить его и так далее.