迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的互斥锁

作者:迹忆客 最近更新:2023/12/17 浏览次数:

在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,让我们深入研究更多方面。


线程和多线程

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
}

在上面的例子中,我们创建了两个名为 mutexmutex1 的 Mutex 对象。我们将使用 mutex1 来控制两个线程之间的切换。创建链表的原因是要有线程的跟踪记录。现在,让我们在上面的代码中添加两个线程。两个线程的名称分别为 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 线程

在我们进入 consumer 线程后,我们立即获取了 mutex1 以在消费期间停止生产。如你所见,我们在名称 C1C2C3 下创建了三个消费者。为了允许一个消费者一次运行,我们还获得了互斥锁。

之后,C1 将成为功能,而 C2C3 将被回收。完成后,mutex 将再次被释放,允许其他消费者发挥作用。

这就是互斥锁在 Java 中的工作方式。运行上述程序后。它将不断显示当前正在使用的生产者线程的数量,以及使用它的消费者的名称。

java 互斥锁示例

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

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 Java 中延迟几秒钟的时间

发布时间:2023/12/17 浏览次数:217 分类:Java

本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。

如何在 Java 中把 Hashmap 转换为 JSON 对象

发布时间:2023/12/17 浏览次数:187 分类:Java

它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。

如何在 Java 中按值排序 Map

发布时间:2023/12/17 浏览次数:171 分类:Java

本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map 进行排序,并列出了一些示例代码来理解它。

如何在 Java 中打印 HashMap

发布时间:2023/12/17 浏览次数:192 分类:Java

本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。

在 Java 中更新 Hashmap 的值

发布时间:2023/12/17 浏览次数:146 分类:Java

本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。

Java 中的 hashmap 和 map 之间的区别

发布时间:2023/12/17 浏览次数:79 分类:Java

本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,

在 Java 中获取用户主目录

发布时间:2023/12/17 浏览次数:218 分类:Java

这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。

Java 中 size 和 length 的区别

发布时间:2023/12/17 浏览次数:179 分类:Java

这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。

Java 中的比较字符是否相等的方法

发布时间:2023/12/17 浏览次数:146 分类:Java

这篇文章是关于在 Java 中使用字符 equals 方法。在 Java 中,我们可以使用 equals(==) 运算符或 Character 类的 equals() 方法来比较两个字符。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便