Методы синхронизации в классе Object

В Android, как и в стандартной библиотеке Java, существуют методы синхронизации в классе Object, которые могут использоваться для обеспечения потокобезопасности и синхронизации различных операций между потоками. Эти методы позволяют контролировать доступ к общим ресурсам и избежать состояния гонки (race condition). Вот основные методы синхронизации, доступные в классе Object:

  1. wait():

    • Метод wait() заставляет текущий поток ожидать, пока другой поток не вызовет метод notify() или notifyAll() на том же объекте.
    • Поток, вызвавший wait(), будет блокирован до тех пор, пока другой поток не вызовет метод notify() или notifyAll() на том же объекте.
  2. notify():

    • Метод notify() используется для уведомления одного из потоков, ожидающих на том же объекте, что состояние объекта может быть изменилось.
    • При вызове notify() один из потоков, ожидающих на объекте, будет разблокирован и может продолжить выполнение.
  3. notifyAll():

    • Метод notifyAll() используется для уведомления всех потоков, ожидающих на том же объекте, что состояние объекта может быть изменилось.
    • Все потоки, ожидающие на объекте, будут разблокированы, и каждый из них может продолжить выполнение.
class Message {
    private String content;

    // Метод для установки сообщения
    public synchronized void setMessage(String message) {
        // Устанавливаем сообщение и будим ожидающий поток
        this.content = message;
        notify();
    }

    // Метод для получения сообщения
    public synchronized String getMessage() throws InterruptedException {
        // Ждем, пока сообщение не будет установлено
        while (content == null) {
            wait();
        }
        // Возвращаем сообщение и сбрасываем его
        String message = content;
        content = null;
        return message;
    }
}

public class MessageExchange {
    public static void main(String[] args) {
        // Создаем объект сообщения
        Message message = new Message();

        // Поток для производства сообщений
        Thread producerThread = new Thread(() -> {
            String[] messages = {"Hello", "How are you?", "Goodbye"};

            // Производим каждое сообщение
            for (String msg : messages) {
                try {
                    Thread.sleep(1000); // Имитируем задержку перед отправкой сообщения
                    message.setMessage(msg);
                    System.out.println("Producer sent: " + msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // Поток для потребления сообщений
        Thread consumerThread = new Thread(() -> {
            // Потребляем каждое сообщение
            for (int i = 0; i < 3; i++) {
                try {
                    String receivedMessage = message.getMessage();
                    System.out.println("Consumer received: " + receivedMessage);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // Запускаем потоки
        producerThread.start();
        consumerThread.start();
    }
}

В этом примере у нас есть два потока: producerThread, который отправляет сообщения, и consumerThread, который получает сообщения. Мы используем методы wait() и notify() для ожидания и отправки сообщений соответственно. Когда producerThread отправляет сообщение, он вызывает setMessage(), который устанавливает сообщение и вызывает notify(), чтобы разбудить consumerThread, который вызывает getMessage() для получения сообщения.