Java의 뮤텍스

Haider Ali 2023년10월12일
  1. 스레딩 및 멀티스레딩
  2. Java의 쓰레드
  3. 뮤텍스
  4. 설명
Java의 뮤텍스

컴퓨터 과학의 세계에서 상호 배제 또는 뮤텍스는 동시성 제어의 속성으로 알려져 있습니다. 모든 컴퓨터는 스레드라고 하는 프로그래밍된 명령어의 가장 작은 시퀀스를 작동합니다. 한 번에 컴퓨터는 단일 스레드에서 작동합니다. 더 나은 이해를 위해 몇 가지 측면을 더 살펴보겠습니다.

스레딩 및 멀티스레딩

CPU는 멀티태스킹을 위해 스레드에서 작동합니다. 각 프로세스는 매우 빠른 속도로 스레드에서 스레드로 지속적으로 이동하여 작동합니다. 예를 들어, 우리가 비디오를 볼 때 비디오의 오디오는 다른 스레드에 있고 사진은 다른 스레드에 있습니다. 이 둘 사이의 지속적인 전환은 매우 빠르며 이를 멀티스레딩이라고 합니다.

Java의 쓰레드

Java에서 스레드를 만드는 것은 클래스를 확장하고 인터페이스를 구현하여 수행됩니다. 멀티스레딩은 CPU 효율성을 최대화하기 위해 프로그램의 두 개 이상의 부분을 동시에 실행할 수 있는 Java 기능입니다. 스레드는 그러한 프로그램의 구성 요소입니다. 따라서 스레드는 프로세스 내의 경량 프로세스입니다.

뮤텍스

둘 이상의 스레드가 다중 스레드 프로그램에서 공유 리소스에 동시에 액세스해야 하므로 예기치 않은 동작이 발생할 수 있습니다. 데이터 구조, 입출력 장치, 파일 및 네트워크 연결은 공유 리소스의 예입니다.

이를 경쟁 조건이라고 합니다. 프로그램의 핵심 섹션은 공유 리소스에 액세스하는 프로그램의 일부입니다. 결과적으로 경쟁 조건을 피하기 위해 중요한 부분에 대한 액세스를 동기화해야 합니다.

가장 기본적인 종류의 동기화 장치는 한 번에 하나의 스레드만 컴퓨터 프로그램의 필수 영역을 실행할 수 있도록 하는 뮤텍스(또는 상호 배제)입니다. 그것은 semaphore라는 클래스에 의해 구현됩니다.

스레드는 뮤텍스를 얻은 다음 중요 섹션에 액세스하고 마지막으로 뮤텍스를 해제하여 임계 영역에 액세스합니다. 한편 다른 모든 스레드는 뮤텍스가 해제될 때까지 차단됩니다. 스레드는 임계 영역을 종료하는 즉시 임계 영역에 들어갈 수 있습니다.

뮤텍스의 경우 잠금 및 잠금 해제 두 가지 방법이 있습니다. 각각 acquire()release()로 알려져 있습니다. 이제 아래의 예를 살펴보십시오.

여기에서 뮤텍스에 대해 자세히 알아보세요.

import java.util.LinkedList; // linked list import
import java.util.concurrent.Semaphore; // semaphore import
public class Mutex {
  static LinkedList<String> WorkingQueue = new LinkedList<String>();
  // track the record of works
  static Semaphore mutex1 = new Semaphore(0); // creating a Semaphore To ImplementLogic
  static Semaphore mutex = new Semaphore(1); // Creating A Mutex
}

위의 예에서 우리는 mutexmutex1이라는 이름으로 두 개의 Mutex 객체를 만들었습니다. 우리는 mutex1을 사용하여 두 스레드 간의 전환을 제어합니다. Linked List를 만드는 이유는 쓰레드의 기록을 가지고 있기 때문입니다. 이제 위의 코드에 두 개의 스레드를 추가해 보겠습니다. ProducerConsumer라는 이름의 두 스레드.

import java.util.LinkedList; // linked list import
import java.util.concurrent.Semaphore; // semaphore import
public class Mutex {
  static LinkedList<String> WorkingQueue = new LinkedList<String>();
  // track the record of works
  static Semaphore mutex1 = new Semaphore(0); // creating a Semaphore To ImplementLogic
  static Semaphore mutex = new Semaphore(1); // Creating A Mutex
  static class Producer extends Thread {
    public void run() { // default run method of thread
      int counter = 1;
      try {
        while (true) {
          String threadName = Thread.currentThread().getName()
              + counter++; // counter is added to have the thread number being used

          mutex.acquire(); // Acquiring  Lock  before Producing so the consumer cannot consume.
          WorkingQueue.add(threadName);
          System.out.println("Producer is prdoucing producing: " + threadName);
          mutex.release(); // releasing After Production ;
          mutex1.release(); // relesing lock for consumer...so consumer can consume after production
          Thread.sleep(2000); // just to Reduce the Execution Speed
        }
      } catch (Exception e) { /*nothing */
      }
    }
  }
  static class Consumer extends Thread {
    String consumerName;
    public Consumer(String name) {
      this.consumerName = name;
    }
    public void run() {
      try {
        while (true) {
          mutex1.acquire(); /// Again Acquiring So no production while consuming
          mutex.acquire(); // Acquring Other consumers lock one consume at one time
          String result = "";
          for (String value : WorkingQueue) {
            result = value + ",";
          }
          System.out.println(consumerName + " consumes value: " + result
              + "Total Size working Queue Size " + WorkingQueue.size() + "\n");
          mutex.release(); // releasing lock for other consumers.
        }
      } catch (Exception e) {
      }
    }
    public static void main(String[] args) {
      Producer producer = new Producer();

      producer.start();
      Consumer c1 = new Consumer("Bill Gates");
      Consumer c2 = new Consumer("Jeff Bezoz");
      Consumer c3 = new Consumer("Mark Zukerberg");
      c1.start();
      c2.start();
      c3.start();
    }
  }
}

설명

위의 코드도 자명하지만 이 설명으로 혼란을 해결할 수 있습니다.

Producer 스레드 내부

위의 프로그램을 실행하면 producer 스레드가 생성됩니다. 해당 스레드 내부에는 무기한으로 실행되는 while 루프가 있습니다. threadName 문자열은 스레드 실행을 표시하기 위한 것입니다. 객체 mutex는 소비자 스레드가 작동하도록 잠금을 획득합니다. (Mutex의 주요 목적, 동시성 제어).

그 후 producer 스레드가 작동합니다. 그런 다음 프로덕션을 위해 이 스레드를 해제해야 합니다. producer 스레드에서 mutex1, consumerproducer 간의 전환을 처리하는 개체를 릴리스합니다. 출시되면 소비자는 소비를 시작합니다. 즉, 소비자 스레드가 작동합니다.

소비자 스레드 내부

consumer 스레드에 들어간 직후 mutex1을 획득하여 소비 중 생산을 중단했습니다. 보시다시피 C1, C2C3이라는 이름으로 세 개의 소비자를 만들었습니다. 한 소비자가 한 번에 작동할 수 있도록 하기 위해 mutex도 인수했습니다.

그 후 C1이 작동하고 C2C3이 획득됩니다. 완료되면 mutex가 다시 릴리스되어 다른 소비자가 작동할 수 있습니다.

이것이 Java에서 뮤텍스가 작동하는 방식입니다. 위의 프로그램을 실행한 후. 현재 사용 중인 생산자 스레드의 수와 이를 사용하는 소비자의 이름이 지속적으로 표시됩니다.

자바 뮤텍스 예제

크기는 프로그램이 실행됨에 따라 계속 증가할 것입니다.

작가: Haider Ali
Haider Ali avatar Haider Ali avatar

Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.

LinkedIn

관련 문장 - Java Threading