Найти тему
DEBAGanov

Java 1565. Мютекс, монитор, семафор.

  • Мютекс (Mutex) - это синхронизационный примитив, который используется для обеспечения взаимного исключения при доступе к общим ресурсам в многопоточной среде. В Java мютексы реализованы с помощью класса java.util.concurrent.locks.ReentrantLock.

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

Пример использования мютекса в Java:

import java.util.concurrent.locks.ReentrantLock;

public class MutexExample {
private static ReentrantLock lock = new ReentrantLock();

public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
lock.lock();
try {
// Критическая секция
System.out.println("Поток 1 захватил мютекс");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("Поток 1 освободил мютекс");
}
});

Thread thread2 = new Thread(() -> {
lock.lock();
try {
// Критическая секция
System.out.println("Поток 2 захватил мютекс");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("Поток 2 освободил мютекс");
}
});

thread1.start();
thread2.start();
}
}

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

  • Монитор (Monitor) Монитор - это синхронизационный примитив, который используется для организации взаимодействия между потоками и обеспечения безопасности при работе с общими ресурсами. В Java мониторы реализованы с помощью ключевого слова synchronized.

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

Пример использования монитора в Java:

public class MonitorExample {
private static final Object monitor = new Object();

public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (monitor) {

// Критическая секция
System.out.println("Поток 1 вошел в монитор");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Поток 1 вышел из монитора");
}
});

Thread thread2 = new Thread(() -> {
synchronized (monitor) {

// Критическая секция
System.out.println("Поток 2 вошел в монитор");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Поток 2 вышел из монитора");
}
});

thread1.start();
thread2.start();
}
}

В этом примере два потока пытаются войти в монитор. Первый поток входит в монитор, выполняет операции в критической секции, а затем выходит из монитора. Затем второй поток входит в монитор и выполняет свои операции в критической секции.

  • Семафор (Semaphore) Семафор - это синхронизационный примитив, который используется для контроля доступа к общим ресурсам в многопоточной среде. В Java семафоры реализованы с помощью класса java.util.concurrent.Semaphore.

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

Пример использования семафора в Java:

import java.util.concurrent.Semaphore;

public class SemaphoreExample {
private static Semaphore semaphore = new Semaphore(2);

public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
semaphore.acquire();

// Критическая секция
System.out.println("Поток 1 получил доступ к ресурсу");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println("Поток 1 освободил ресурс");
}
});

Thread thread2 = new Thread(() -> {
try {
semaphore.acquire();

// Критическая секция
System.out.println("Поток 2 получил доступ к ресурсу");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println("Поток 2 освободил ресурс");
}
});

thread1.start();
thread2.start();
}
}

В этом примере два потока пытаются получить доступ к ресурсу, ограниченному семафором. Первый поток получает доступ к ресурсу, выполняет операции в критической секции, а затем освобождает ресурс. Затем второй поток получает доступ к ресурсу и выполняет свои операции в критической секции.

3019 вопрос-ответ по Java

Курс Spring Framework

Tелеграмм каналDEBAGanov

Мое резюмеDEBAGanov

Если вам понравилось, буду признателен за подписку.