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 互斥锁示例

随着程序运行,大小将不断增加。