深入解析哈希表、哈希映射和并发哈希映射的区别,以及死锁的成因和解决方案

news2024/11/25 1:43:55

目录

  • 死锁
    • 死锁产生条件
    • 解决方案
  • HashTable
  • ConcurrentHashMap
  • HashMap

死锁

死锁是多线程编程中常见的问题,当两个或多个线程互相等待对方持有的资源而无法继续执行时,就会发生死锁。这种情况下,程序会陷入无法恢复的状态,造成程序停滞或崩溃。以下是死锁产生的常见原因和解决方案。

死锁产生条件

  1. 互斥访问资源:多个线程相互竞争访问资源,如果资源被一个线程持有,其他线程无法获取到该资源。
  2. 不可抢占:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  3. 循环等待:多个线程形成环形的资源依赖关系,每个线程都在等待下一个线程释放资源。
  4. 占用并等待:线程在持有一个资源的同时,又请求其他资源,导致其他线程无法继续执行。
    当上述四个条件都成立时,死锁变形成了。

可以举例“哲学家就餐问题”,有一群哲学家围着一张桌子吃饭,每两个哲学家之间放一个筷子,哲学家只做两件事:思考人生 或者 吃面条。 思考人生的时候就会放下筷子。吃面条就会拿起左右两边的筷子(先拿起左边, 再拿起右边),哲学家发现筷子拿不起来就会阻塞等待思考人生。五个哲学家同一时刻同时拿起左的筷子,再去拿右边的筷子就会发现筷子已被占有,就会阻塞等待,进行思考人生,哲学家们互相挂起等待就会形成“死锁”。

解决方案

如何解决死锁呢,那就是打破死锁形成的四个必要条件。

  • 破坏互斥条件:对于一些非必要的资源,可以改为共享资源,多个线程可以同时访问,从而避免互斥。
  • 破坏占用并等待:当线程需要多个资源时,一次性获取所需资源,而不是一个个依次获取,或者采用资源预分配的策略。
  • 破坏循环等待:通过对资源进行编号或者按照固定的顺序申请资源,避免形成循环等待。

其中最容易破坏的就是 “循环等待”

破坏循环等待最常用的一种死锁阻止技术就是锁排序。假设有 N 个线程尝试获取 M 把锁,就可以针对 M 把锁进行编号。N 个线程尝试获取锁的时候,都按照固定的按编号由小到大顺序来获取锁。这样就可以避免环路等待。

下面分别演示会产生环路等待的代码与不会产生环路等待的代码。
可能会产生环路等待:

  public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread t1 = new Thread(){
            @Override
            public void run() {
                //获取锁
                synchronized (lock1){
                    synchronized (lock2){
                       
                    }
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                synchronized (lock2){
                    synchronized (lock1){
                     
                    }
                }
            }
        };
        t1.start();
        t2.start();
    }

不会产生环路等待的代码:

  public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread t1 = new Thread(){
            @Override
            public void run() {
                //获取锁
                synchronized (lock1){
                    synchronized (lock2){

                    }
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                synchronized (lock1){
                    synchronized (lock2){

                    }
                }
            }
        };
        t1.start();
        t2.start();
    }

约定好顺序,先获取lock1锁再获取lock2锁在这里插入图片描述

HashTable

HashTable只是对关键方法加上了 synchronized 关键字。
在这里插入图片描述
这就相当于对hashtable对象直接进行加锁。

  • 多个线程访问同一个hashtable就会发送锁冲突
  • 由于同步锁的存在,哈希表的性能相对较差。在高并发情况下,多线程的竞争可能会导致性能下降。
  • 哈希表不允许键和值为 null。

ConcurrentHashMap

  • 每个链表的头结点作为锁对象,降低了锁冲突概率
  • 读操作没有加锁,写操作进行了加锁依旧使用synchronized
  • 充分利用 CAS 特性
  • 优化了扩容方式
    1. 化整为零,当发现需要扩容时,会创建一个新的数组,并进行一部分的数据搬运
    2. 插入新元素时就会直接给新表里插入元素,并搬运一部分数据
    3. 删除元素时,新旧表都会进行查找,元素在那个表上,在那个表上删除
    4. 直到旧表元素搬运完成,才会把旧表进行删除

只有当两个线程访问同一个哈希桶上的数据才会进行锁冲突。

HashMap

  • 线程不安全:哈希映射是非线程安全的,不适用于多线程环境。在多线程环境下使用时,可能导致数据不一致的问题。
  • 性能:哈希映射的性能较好,由于没有同步锁的开销,能够更快地执行插入、查找和删除操作。

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

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

相关文章

215. 数组中的第K个最大元素+17.14. 最小K个数(优先级队列)

目录 一、第K个最大元素 二、代码 三、最小K个数 四、代码 一、第K个最大元素 215. 数组中的第K个最大元素 - 力扣&#xff08;LeetCode&#xff09; 二、代码 class Solution { public:int findKthLargest(vector<int>& nums, int k) {priority_queue data(nu…

MySQL数据库的存储引擎

目录 一、存储引擎概念 二、存储引擎 2.1MyISAM 2.11MyISAM的特点 2.12MyISAM表支持3种不同的存储格式&#xff1a; 2.2 InnoDB 2.21InnoDB特点介绍 三、InnoDB与MyISAM 区别 四、怎么样选择存储引擎 五、查看存储引擎 六、查看表使用的存储引擎 七、修改存储引擎 …

Leetocde 404. 左叶子之和

左叶子之和 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 提示: 节点数在 [1, 1000] 范围内-1000 < Node.val < 1000 采用的是递归法 s1. 确定递归函数的参数和返回值 s2. 确定终止条件 if(root NULL)return 0;s3. 确定单层递归的逻辑 当遇到左叶…

华为云Stack的学习(七)

八、华为云Stack存储服务介绍 1.云硬盘EVS 云硬盘&#xff08;Elastic Volume Service&#xff0c;EVS&#xff09;&#xff0c;又名磁盘&#xff0c;是一种虚拟块存储服务&#xff0c;主要为ECS&#xff08;Elastic Cloud Server&#xff09;和BMS&#xff08;Bare Metal Se…

2023年苏工展丨合共软件诚邀您参观苏州工业制造展,全新一代制造运营管理平台RockPlus MOM即将亮相!

2023年09月25日至27日一场智能制造的盛宴将于苏州国际博览中心盛大召开&#xff0c;合共软件受邀参展&#xff0c;展位&#xff1a;D馆1区A06-8。此次展览中&#xff0c;我们将向参观者展示最新产品——RockPlus MOM&#xff0c;一种颠覆性的数字化智能制造解决方案。上海合共软…

东芝第一代20T MAMR HDD实现PB级存储方案

近日&#xff0c;荷兰国际广播电视技术展览会(IBC 2023&#xff09;上东芝展示出来基于20T MARM HDD MARM&#xff0c;该盘基于FC-MAMR新技术&#xff0c;不是传统的CMR。 该产品的SPEC信息&#xff1a; 东芝本次公布的解决方案涉及的系统硬件主要包括&#xff1a; 东芝企业20…

新手学习:ArcGIS 提取SHP 路网数据、节点

新手学习&#xff1a;ArcGIS 提取SHP 路网数据、节点 参考连接 OSM路网提取道路节点 ArcGIS&#xff1a;如何创建地理数据库、创建要素类数据集、导入要素类、表&#xff1f; 1. 导入开源路网SHP文件 2. 在交点处打断路网数据 未打断路网数据 有一些路径很长&#xff0c;…

FreeRTOS基础七:资源管理

简介 在多任务环境下&#xff0c;多个任务访问同一个资源会面临挑战。若不加防护机制&#xff0c;多个任务或者中断对同一个资源的访问可能会导致错误。 例如&#xff0c;任务A需要在屏幕显示“Hello world”&#xff0c;他向屏缓冲区幕写入字符串"Hello w"时被任务…

使用 Spring Security 实现安全认证的 Spring Boot 应用

使用 Spring Security 实现安全认证的 Spring Boot 应用 在开发Web应用程序时&#xff0c;保护用户的数据和应用程序是至关重要的。Spring Security是Spring生态系统的一部分&#xff0c;它提供了一种强大的方法来实现身份验证和授权。本文将详细介绍如何使用Spring Security来…

树莓派登录后运行PYTHON

网上记录的登录方式 通过服务 通过rd.local 通过 通过服务启动&#xff0c;可能会导致PYTHON代码部份未运行&#xff08;加SLEEP后可能也不行&#xff09; 注意完整路径 启动前先测试一下&#xff0c;否则可能启动后无效果 开机自启动脚本方法之一&#xff08;.Desktop文件…

uniapp iOS离线打包——原生工程配置

uniapp iOS离线打包&#xff0c;如何配置项目工程&#xff1f; 文章目录 uniapp iOS离线打包&#xff0c;如何配置项目工程&#xff1f;工程配置效果图DebugRelease 配置工程配置 Appkey应用图标模块及三方SDK配置未配置模块错误配置模块TIP: App iOS 离线打包 前提&#xff1a…

Javascript小案例-进度条(配置对象版)

gif演示图&#xff1a; 代码&#xff1a; 进度条(配置对象版).html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&…

一个关于IntroductionAdvisor的bug

一个关于IntroductionAdvisor的bug public class TestMain {public static void main(String[] args) {// 1. 准备被代理的目标对象People peo new People();// 2. 准备代理工厂ProxyFactory pf new ProxyFactory();// 3. 准备introduction advice,advice 持有需要额外添加的…

ps[001] 初学创建剪切蒙版

前置条件&#xff1a;PS2020版本 技能应用&#xff1a;ps 海报标题和图片结合 1、画布1300*1300像素&#xff0c;altdel设置背景为前景色 2、准备一张绿色的海报&#xff0c;可以百度宫崎骏&#xff0c;找张绿色的图片就可以了 3、拉个文字款&#xff0c;写个SUMMER英文体&a…

java面试题-集合类基础

导学 这次课程主要涉及到的是List和Map相关的面试题&#xff0c;比较高频就是 ArrayList LinkedList HashMap ConcurrentHashMap ArrayList底层实现是数组LinkedList底层实现是双向链表HashMap的底层实现使用了众多数据结构&#xff0c;包含了数组、链表、散列表、红黑树等…

机器学习笔记 - k-NN算法的数学表达

一、概述 所有的机器学习算法都是有假设前提的。k-NN算法的假设前提是相似的输入有相似的输出。其分类规则是对于测试输入x,在其k个最相似的训练输入中分配最常见的标签。 k-NN 的正式定义: 对于一个待测试数据。 将的个最近邻的集合表示为 。的正式定义为 ,并且。(意思就是…

Glitch free 无毛刺时钟切换电路,时钟无缝切换,时钟无毛刺切换技术

、无毛刺时钟切换电路&#xff0c;又叫 Glitch free 电路、时钟无缝切换电路&#xff0c;在笔试中遇到过&#xff0c;如果没有接触过&#xff0c;很可能无从下手。 随着越来越多的多时钟应用于当今的芯片中&#xff08;尤其是在通信领域&#xff09;&#xff0c;在芯片运行时经…

shap-An introduction to explainable AI with Shapley values

An introduction to explainable AI with Shapley values 训练模型检查模型系数使用部分依赖图的更完整的图片从部分相关性图中读取SHAP值Shapley值的可加性解释additive regression模型解释non-additive boosted tree模型解释线性逻辑回归模型解释non-additive boosted tree逻…

Jenkins “Trigger/call builds on other project“用法及携带参数

1.功能 “Trigger/call builds on other project” 功能是 Jenkins 中的一个特性&#xff0c;允许您在某个项目的构建过程中触发或调用另一个项目的构建。 当您在 Jenkins 中启用了 “Trigger/call builds on other project” 功能并配置了相应的触发条件后&#xff0c;当主项…

python实验2

1、实验题目&#xff1a;个人用户信息注册 模拟用户个人信息注册&#xff0c;需要输入用户个人信息 姓名、性别、年龄、血型、身高、电话 信息&#xff0c;并输出显示。 源代码&#xff1a; print(用户个人信息注册) name input("请输入您的姓名&#xff1a;") sex…