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 中的工作方式。运行上述程序后。它将不断显示当前正在使用的生产者
线程的数量,以及使用它的消费者
的名称。
随着程序运行,大小将不断增加。
转载请发邮件至 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 对象的详细例子。
发布时间: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 是用于以键值对存储数据的接口,
发布时间: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() 方法来比较两个字符。