AbstractQueuedSynchronizer的独占锁和共享锁

AbstractQueuedSynchronizer(AQS)提供了两种类型的锁:独占锁和共享锁。

  1. 独占锁(Exclusive Lock)

    • 独占锁模式只允许一个线程同时获取锁。当一个线程获取了独占锁时,其他线程必须等待该线程释放锁之后才能获取。
    • 在AQS中,独占锁通过实现tryAcquiretryRelease方法来控制锁的获取和释放过程。通常,这些方法会被子类覆盖以提供特定的锁语义。
    • 例如,ReentrantLock就是一个基于AQS实现的独占锁,它允许线程在重入时多次获取同一把锁。
  2. 共享锁(Shared Lock)

    • 共享锁模式允许多个线程同时获取锁,以便并发访问共享资源。然而,在某些情况下,共享锁可能会导致饥饿或死锁。
    • 在AQS中,共享锁通过实现tryAcquireSharedtryReleaseShared方法来控制锁的获取和释放过程。这些方法也可以被子类覆盖以提供自定义的共享锁语义。
    • 例如,ReadWriteLock就是基于AQS实现的一个常见的共享锁,它允许多个线程同时获取读锁,但只允许一个线程获取写锁。

ReentrantLock
下面是一个使用 ReentrantLock 的简单示例:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final Lock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock(); // 获取锁try {count++; // 对共享变量进行操作} finally {lock.unlock(); // 释放锁}}public int getCount() {return count;}public static void main(String[] args) {ReentrantLockExample example = new ReentrantLockExample();// 创建多个线程对共享变量进行操作Runnable task = () -> {for (int i = 0; i < 1000; i++) {example.increment();}};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 输出最终的共享变量值System.out.println("Final count: " + example.getCount());}
}

在这个例子中,ReentrantLockExample 类包含一个 ReentrantLock 对象和一个共享变量 countincrement() 方法用于对 count 变量执行递增操作,其中使用 lock() 方法获取锁,执行完操作后使用 unlock() 方法释放锁。在 main 方法中,创建了两个线程分别执行 increment() 方法,最后输出 count 变量的最终值。

使用 ReentrantLock 的优点之一是它支持重入性,允许同一线程在持有锁的情况下多次获取该锁,避免了死锁的发生。

ReadWriteLock
下面是一个使用 ReadWriteLock 的简单示例:

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReadWriteLock lock = new ReentrantReadWriteLock();private int data = 0;public void writeData(int newData) {lock.writeLock().lock(); // 获取写锁try {data = newData; // 写入新数据System.out.println("Write data: " + newData);} finally {lock.writeLock().unlock(); // 释放写锁}}public int readData() {lock.readLock().lock(); // 获取读锁try {System.out.println("Read data: " + data); // 读取数据return data;} finally {lock.readLock().unlock(); // 释放读锁}}public static void main(String[] args) {ReadWriteLockExample example = new ReadWriteLockExample();// 创建多个线程读取数据Runnable readTask = () -> {for (int i = 0; i < 5; i++) {example.readData();}};// 创建一个线程写入数据Runnable writeTask = () -> {for (int i = 1; i <= 5; i++) {example.writeData(i);try {Thread.sleep(1000); // 休眠1秒} catch (InterruptedException e) {e.printStackTrace();}}};// 启动读线程和写线程Thread reader1 = new Thread(readTask);Thread reader2 = new Thread(readTask);Thread writer = new Thread(writeTask);reader1.start();reader2.start();writer.start();}
}

在这个例子中,ReadWriteLockExample 类包含一个 ReadWriteLock 对象和一个共享变量 datawriteData() 方法用于写入新数据,其中使用 writeLock() 方法获取写锁,执行完写操作后释放写锁。readData() 方法用于读取数据,其中使用 readLock() 方法获取读锁,读取完数据后释放读锁。

main 方法中,创建了两个读线程和一个写线程,分别执行读取和写入操作。读线程可以同时持有读锁,但写线程必须独占写锁,以确保写操作的原子性和一致性。

这个例子展示了 ReadWriteLock 的特性,读线程可以并发地访问共享数据,而写线程在执行写操作时会独占资源,以避免读写操作之间的竞争和冲突。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端】eslint 禁用命令

/* eslint-disable */ ESLint 在校验的时候就会跳过后面的代码还可以在注释后加入详细规则&#xff0c;这样就能避开指定的校验规则了 /* eslint-disable no-new */常用&#xff1a; rules: {"comma-dangle": ["error", "never"], //是否允许对…

Arduino开发 esp32cam+opencv人脸识别距离+语音提醒

效果 低于20厘米语音提醒字体变红 QQ录屏20240406131651 Arduino代码 可直接复制使用&#xff08;修改自己的WIFI) #include <esp32cam.h> #include <WebServer.h> #include <WiFi.h> // 设置要连接的WiFi名称和密码 const char* WIFI_SSID "gumou&q…

MYSQL 8.0版本修改用户密码(知道登录密码)和Sqlyog错误码2058一案

今天准备使用sqlyog连接一下我Linux上面的mysql数据库&#xff0c;然后就报如下错误 有一个简单的办法就是修改密码为password就完事!然后我就开始查找如何修改密码! 如果是需要解决Sqlyog错误码2058的话&#xff0c;执行以下命令&#xff0c;但是注意root对应host是不是loca…

Fecify站点斗篷cloak

斗篷cloak站点斗篷模式功能发布&#xff01;全新的应用场景&#xff0c;该模式是针对推广不用GMC&#xff0c;而是通过facebook&#xff0c;或者其他的一些平台/工具推广&#xff0c;这些推广方式的特点是&#xff1a;不需要商品的图片&#xff0c;或者说不会排查商品图片的侵权…

基础语法复习

常用的定义&#xff1a; 读取数据加速&#xff1a; input sys.stdin.readline 设置递归深度&#xff1a; sys.setrecursionlimit(100000) 记忆化搜索&#xff1a; from functools import lru_cache lru_cache(maxsizeNone) 计数器&#xff1a; Counter 类是一个非常有…

P8707 [蓝桥杯 2020 省 AB1] 走方格

原题链接&#xff1a;[蓝桥杯 2020 省 AB1] 走方格 - 洛谷 目录 1.题目描述 2.思路分析 3.代码实现 1.题目描述 2.思路分析 题目大意&#xff1a;现在有个人站在第 1 行第 1 列&#xff0c;要走到第 i 行第 j 列&#xff08;每次只能向右或者向下走&#xff09;&#xff0…

第四百五十回

文章目录 1. 知识回顾2. 使用方法3. 示例代码4. 经验与总结4.1 经验分享4.2 内容总结 我们在上一章回中介绍了"overlay_tooltip简介"相关的内容&#xff0c;本章回中将再谈flutter_native_splash包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我…

计算机的发展趋势

本文 我们来说计算机的发展趋势 目前来讲 计算机是朝着 巨型化 微型化 网络化 智能化发展 巨型化 指功能巨型化 是指其高速运算、大存储容量和强功能的巨型计算机。其运算能力一般在每秒百亿次以上、内存容量在几百兆字节以上。 主要用于航空航天、军事、气象、人工智能、生…

业务逻辑之身份认证

实现业务功能的逻辑不严谨导致的漏洞 业务流程分类 用户身份验证 会话管理 角色和权限识别 资源访问 交易和支付 密码重置和安全设置 日志记录和审计 url参数 某些参数可以表示用户权限&#xff08;身份&#xff09; http请求头 用户身份验证信息存在请求头部中的 Authorizatio…

单链表学习

//静态链表&#xff0c;只往后看&#xff0c;找前面必须遍历 //算法题用数组解题更快速 //初始化,头节点为空 //将x插入到头节点 //将x插到结点k的后面 //将下标k的后面的点删掉 #include<algorithm> #include<iostream> #include<cstring> #include<queu…

Leetcode:27.移除元素

题目要求 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

智能单灯控制器 计讯物联TL112

智能单灯控制器集成了先进技术的照明控制设备&#xff0c;它极大地改变了传统照明方式&#xff0c;并使之更加智能化。计讯物联智能单灯控制器TL112广泛应用于道路、景区、园区、隧道等场景智慧路灯杆使用。      智能单灯控制器通过集成最先进的传感器、控制模块和通信技术…

基于vue实现动态table

1、代码 <div style"height: 600px; overflow: scroll;"> <!-- height: 600px; overflow: scroll;作用是超出页面可以滑动 --><div ng-repeat"row in entity.procedureList"><cb-title title"工序{{row.procedireLocation}}&quo…

SpringBoot整合RabbitMQ,三种交换机类型示例

SpringBoot整合RabbitMQ&#xff0c;三种交换机类型示例 1、流程概括 2、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>3、配置RabbitMQ连接 在a…

【C++成长记】C++入门 |auto、范围for、nullptr

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、auto关键字 1、auto简介 2、auto的使用细则 &#xff08;1&#xff09; auto与指针和引用结合起…

多线程入门

文章目录 多线程相关的概念什么是多线程多线程的创建方式继承Thread方式实现Runable方式两种方式比较Thread类中常用方法 多线程相关的概念 并发与并行 并行&#xff1a;在同一时刻&#xff0c;有多个任务在多个CPU上同时执行。并发&#xff1a;在同一时刻&#xff0c;有多个任…

[网鼎杯 2020 玄武组]SSRFMe

[网鼎杯 2020 玄武组]SSRFMe 源码 <?php function check_inner_ip($url) {$match_resultpreg_match(/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/,$url);if (!$match_result){die(url fomat error);}try{$url_parseparse_url($url);}catch(Exception $e){die(url foma…

Linux内核

一、 内核开发与逻辑开发对比 内核开发&#xff1a; 需要应用程序调用API去在操作系统里对硬件进行操作。操作系统不允许用户直接去通过置GPIO口1或者0去控制硬件&#xff0c;为了管理这一切。操作系统将整个开发中分成了两个空间&#xff0c;一个是用户空间&#xff08;上两…

HarmonyOS 开发-Navigation页面跳转对象传递案例

介绍 本示例主要介绍在使用Navigation实现页面跳转时&#xff0c;如何在跳转页面得到转入页面传的类对象的方法。实现过程中使用了第三方插件class-transformer&#xff0c;传递对象经过该插件的plainToClass方法转换后可以直接调用对象的方法&#xff0c; 效果图预览 使用说…

pta L1-011 A-B

L1-011 A-B 分数 20 全屏浏览 切换布局 作者 陈越 单位 浙江大学 本题要求你计算A−B。不过麻烦的是&#xff0c;A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉&#xff0c;剩下的字符组成的就是字符串A−B。 输入格式&#xff1a; 输入在2行中先后给出…