HOWTO · Java

Java 中的互斥鎖

瞭解有關 Java 中互斥鎖的一切

本頁內容

在電腦科學領域,互斥或互斥被稱為併發控制的屬性。每臺計算機都使用稱為執行緒的最小程式指令序列。有一次,計算機在一個執行緒上工作。為了更好地理解,讓我們深入研究更多方面。

執行緒和多執行緒

CPU 線上程上工作以進行多工處理。每個程序都以非常快的速度不斷地從一個執行緒轉移到另一個執行緒。例如,當我們觀看視訊時,視訊的音訊在不同的執行緒上,而圖片在不同的執行緒上。這兩者之間的不斷切換是非常快的,它被稱為多執行緒。

Java 中的執行緒

在 Java 中建立執行緒是通過擴充套件類和實現介面來完成的。多執行緒是一種 Java 特性,它允許同時執行程式的兩個或多個部分,以最大限度地提高 CPU 效率。執行緒是此類程式的一個元件。因此,執行緒是程序中的輕量級程序。

互斥鎖

在多執行緒程式中,兩個或多個執行緒可能需要同時訪問共享資源,從而導致意外行為。資料結構、輸入輸出裝置、檔案和網路連線都是共享資源的例子。

它被稱為競爭條件。程式的關鍵部分是訪問共享資源的程式部分。因此,我們必須同步對關鍵部分的訪問以避免競爭條件。

最基本的一種同步器是互斥(或互斥),它確保一次只有一個執行緒可以執行計算機程式的基本區域。它由一個名為 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
}

在上面的例子中,我們建立了兩個名為 mutex 和 mutex1 的 Mutex 物件。我們將使用 mutex1 來控制兩個執行緒之間的切換。建立連結串列的原因是要有執行緒的跟蹤記錄。現在,讓我們在上面的程式碼中新增兩個執行緒。兩個執行緒的名稱分別為 Producer 和 Consumer。

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,該物件負責處理 consumer 和 producer 之間的切換。釋放後,消費者將開始消費,換句話說,消費者執行緒將起作用。

Consumer 執行緒

在我們進入 consumer 執行緒後,我們立即獲取了 mutex1 以在消費期間停止生產。如你所見,我們在名稱 C1、C2 和 C3 下建立了三個消費者。為了允許一個消費者一次執行,我們還獲得了互斥鎖。

之後,C1 將成為功能,而 C2 和 C3 將被回收。完成後,mutex 將再次被釋放,允許其他消費者發揮作用。

這就是互斥鎖在 Java 中的工作方式。執行上述程式後。它將不斷顯示當前正在使用的生產者執行緒的數量,以及使用它的消費者的名稱。

java 互斥鎖示例

隨著程式執行,大小將不斷增加。