Java语法六:线程安全以及死锁

news2025/1/11 20:57:05

前言:

接下来我们要了解一下,线程安全的集合类有哪些?什么是死锁以及怎么避免死锁问题。

1.多线程环境使用哈希表

1.1:HashTable

只是简单的把关键方法加上synchronized关键字。

public synchronized V put(K key, V value)

public synchronized V get(Object key)

这个是针对this来进行加锁。当多个线程来访问这个HashTable的时候,无论是啥样的操作,无论是什么样的数据,都会出现锁竞争。

一个HashTable只有一把锁,两个线程访问HashTable 中任意的数据都会出现锁竞争。

 这相当于直接针对hashtable对象本身加锁。

如果多线程访问同一个hashtable就会直接造成锁冲突。

size属性也是通过synchronized来控制同步,也是比较慢的。

一旦触发扩容,就有该线程完成整个扩容过程,这个过程会涉及大量的元素拷贝,效率会比较低。这是一次就完成整个扩容。

1.2:ConcurrentHashMap

 1.读操作没有加锁(但是使用了volatile保证从内存读取结果),只对写操作进行加锁,加锁的方式仍然是使用synchronized。但只是"锁桶"(用每个链表的头节点作为锁对象)这样减低锁冲突的概率)。

2.充分利用CAS特性,比如size属性通过CAS来更新,避免出现重量级锁的情况。

3.优化了扩容方式:化整为零。

   。发现需要扩容的线程,每次操作只搬运一点点,通过多次操作完成整个搬运的过程。同时维护一个新的HashMap和一个旧的,查找的时候即需要查找旧的也要查找新的,插入的时候只插入新的,直到搬运完毕再销毁旧的。

1.3:面试题

hashtable和HashMap,ConcurrentHashMap之间的区别:

HashMap:线程不安全,key允许为null

HashTable:线程安全,使用synchronized锁HashTable对象,效率低,key不允许null.

ConcurrentHashMap:线程安全,使用synchronized锁每个链表头结点,锁冲突概率降低,充分利用CAS机制,优化了扩容机制,key不允许为null.

2:死锁

2.1:死锁是什么

多个线程同时被阻塞,他们中一个或者全部都在等待莫个资源被释放,由于线程被无限期的阻塞,因此程序不可能正常终止。

举一个例子:

你和你朋友一起去吃过桥米线,你首先拿到了辣椒油,你朋友拿到了醋,你们都要拿到醋和辣椒油才会吃。当你要你朋友先给你醋,你朋友要你先给他辣椒油。你们两个就一直坚持不下。这样就一直干着,这就叫死锁。

2.2:死锁的案例

1.一个线程,一把锁,连续加锁两次,如果这把锁是不可重入锁,就会形成死锁。

2.两个线程,先对自己拥有的锁加锁,在获取对方的锁。

  public static void main(String[] args) {
        Object lajiao =new Object();
        Object cu=new Object();
        Thread me=new Thread(()->{
            synchronized (lajiao) {
                System.out.println("me拿到了辣椒油");
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (cu) {
                    System.out.println("me拿到醋了");
                }
            }
        });
        Thread him=new Thread(()->{
            synchronized (cu) {
                System.out.println("him拿到醋了");
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lajiao) {
                    System.out.println("him拿到辣椒油");
                }
            }
        });
        me.start();
        him.start();
    }
}

3.多个线程多把锁---哲学家就餐问题

 每个哲学家只做两件事:思考人生或者吃面条,思考人生的时候就会放下筷子。吃面条就会拿起左右两边的筷子(先拿起左手,再拿起右手)

如果哲学家发现筷子拿不起来(被别人占用),就会阻塞等待。

假设同一个时刻,哲学家同时拿起左手边的筷子,然后再尝试拿右手的筷子,就会发现右手的筷子都被占用,由于哲学家互不相让,这时候就形成了死锁。

2.3:死锁产生的四个必要条件:

互斥使用:即当资源被一个线程使用(占有)时,别的线程不能使用。

例如:线程1拿到了锁,线程2要想拿到锁,只能等着。

不可抢占:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

例如:线程1拿到了锁,线程2要想要拿到锁,只等等到线程1主动释放锁。

请求和保持:即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

例如:线程1拿到锁A,再尝试获取锁B,但A这把锁还是保持的。(不会因为获取锁B,把锁A给释放了)。

以上三个条件都是锁自身的性质。

循环等待:即存在一个等待队列:p1占有p2的资源,p2占有p3的资源,p3占有p1的资源,这样就会形成一个循环等待。

2.4:如何避免死锁

上面讲了四个形成死锁的必要条件,要四个条件都要满足。但前三个都是锁。是无法动的,所以我们要避免死锁,只能破环循环等待。

破坏循环等待:N个线程尝试获取锁的时候,都按照固定的按标号从小到大的顺序来获取锁,这样就可以避免环路等待。

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

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

相关文章

(1分钟速览)最近邻搜索--激光SLAM常用必杀技

学习kdtree的数据结构,和二叉树的思想大体上算是比较相似的。参考博客:https://blog.csdn.net/dive_shallow/article/details/113136145建树,一个递归的操作。这里的删除操作很好理解,分左子树和右子树两种情况。如果是左子树那么…

Go语言设计与实现 -- 内存对齐机制

什么是内存对齐 为了能让CPU可以更快的存取到各个字段,Go编译器会帮你把struct结构体做数据的对齐。所谓的数据对齐,是指内存地址是所存储数据的大小(按字节为单位)的整数倍,以便CU可以一次将该数据从内存中读取出来。…

每天五分钟机器学习:推荐系统中所有用户的损失函数是什么?

本文重点 我们分析机器学习算法都是从损失函数的角度来说的,为了找到最佳的参数θ,可以最小化损失函数,那么本节课程我们将学习基于内容的推荐系统的损失函数是什么? 数据集 我们将每一个电影称为样本,每个电影有两个特征x1、x2,其中x1表示该电影为恐怖片的程度,x2表…

测试开发 | 跨平台设备管理方案 Selenium Grid

Selenium Grid 是 Selenium 的三大组件之一,它可以在多台机器上并行运行测试,集中管理不同的浏览器版本和浏览器配置。通过将客户端命令发送到远程浏览器的实例, Selenium Grid 允许在远程计算机 (虚拟或真实) 上执行 WebDriver 脚本. 它旨在提供一种在多…

SSL证书的类型

SSL证书类型分3类:DV OV EV.域名型(DV)SSL证书: 信任等级一般,只需验证网站的真实性便可颁发证书保护网站。企业型(OV)SSL证书: 信任等级强,须要验证企业的身份,审核严格&#xff0c…

VS2017基于CLR运行环境的VC++.NET界面编程(数据库为mysql)

此篇献给暨南大学珠海校区还在用VS2013编写VC++.NET界面程序的苦逼们! 文章分为四个部分: 1、运行环境的搭建 2、数据库的连接 3、控件介绍 4、程序编写示例 程序效果演示视频和程序源码及数据库文件附于文末。 一、运行环境的搭建 VS自从2013版本后淘汰VC++.NET,编写界面…

恒星物联河道流量监测站——雷达流量计

一、产品概述 河道流量监测站是一款采用一体化设计的河道流量智能监测设备,设备由河道雷达流量计、遥测终端机、太阳能供电系统组成。雷达流量计采用先进的K波段平面雷达技术,通过非接触的方式测量水体的流速和水位,根据内置的软件算法&…

TCP协议重点总结(万字总结-附实例)

文章目录前言一、网络的原生情况二、TCP协议2.1 TCP的特点2.2 TCP协议段格式2.3 TCP原理2.3.1 确认应答机制(可靠机制)2.3.2 序列号2.3.3 超时重传机制(可靠机制)2.3.4 连接管理机制(可靠机制)2.3.5 滑动窗…

RabbitMQ的简介和简单使用

同步调用异步调用MQRabbitMQ的使用docker拉取docker pull rabbitmq:3-management启动容器docker run \-e RABBITMQ_DEFAULT_USERitcast \ (账号)-e RABBITMQ_DEFAULT_PASS123321 \ (密码)--name mq \--hostname mq1 \-p 15672:156…

开发工具中SpringBoot使用外置Tomcat启动 (亲测有效)-第458篇

历史文章(文章累计450) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 SpringBoot添加外部jar包及打包(亲测有…

评测5款国内外免费远控,谁是最好用第一名?

远程控制应用不少人都有了解使用过,尤其是会常用电脑进行工作的群体,比如程序员、设计师、运维、文员等岗位。在隔离居家远程办公时,通过家里的手机、平板或电脑跨系统、跨设备操控公司所用的办公电脑,就能及时处理工作内容&#…

前端使用lottie-web,使用AE到处的JSON动画贴心教程

Lottie简介 官方介绍:Lottie是一个库,可以解析使用AE制作的动画(需要用bodymovie导出为json格式),支持web、ios、android、flutter和react native。 在web端,lottie-web库可以解析导出的动画json文件,并将其…

02_FreeRTOS移植

目录 获取FreeRTOS源码 FreeRTOS源码内容 FreeRTOS内核 Demo文件夹 Source文件夹 portable文件夹 FreeRTOS移植 移植步骤 移植详解 实验源码: 获取FreeRTOS源码 FreeRTOS官网:https://www.freertos.org/ FreeRTOS源码内容 FreeRTOS内核 Demo文件夹 Demo文件夹里面就…

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享(15)

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限,如果错误欢迎批评指正。 第四章:Protein Binding Leads to Biological Actions (蛋白质的结合会产生生物作用) 如果我们想要对一个结合过…

Java 泛型中的通配符详解

目录 1、如何定义和使用上界通配符? 2、如何定义和使用无界通配符? 3、如何定义和使用下界通配符? 4、如何使用通配符定义泛型类或接口之间的子类型关系? 5、通配符的捕获和辅助方法 6、通配符使用指南 在泛型代码中&#x…

C++ txt文本文件处理系统(c++学习小例子)

C++ txt文本文件处理系统(c++学习小例子) 一、界面示例二、 要求2.1 数据格式2.2 实现功能三、代码3.1 classfi.h3.2 classfi.cpp3.3 main.cpp四、 使用说明一、界面示例 二、 要求 2.1 数据格式 现有DEM数据,其格式为DEM_data.txt,可在文章末尾下载。文本存储格式如下: …

用javascript分类刷leetcode19.数组(图文视频讲解)

数组操作的时间复杂度 Access:O(1) Search:O(n) Insert: 平均O(n),最好的情况下O(1),也就是在数组尾部插入O(1),最坏的情况下O(n) Delete;平均O(n),最好的情况下O(1),…

力扣刷题记录——367. 有效的完全平方数、383. 赎金信、387. 字符串中的第一个唯一字符、389. 找不同

本专栏主要记录力扣的刷题记录,备战蓝桥杯,供复盘和优化算法使用,也希望给大家带来帮助,博主是算法小白,希望各位大佬不要见笑,今天要分享的是——《367. 有效的完全平方数、383. 赎金信、387. 字符串中的第…

LightDB单机安装

LightDB单机安装 LightDB官网:https://www.hs.net/lightdb 下载安装包:lightdb-x-13.8-22.3-7953-el7.x86_64.zip 前置准备 防火墙配置(选择一种操作) firewall防火墙 firewall-cmd --permanent --add-port5432/tcp firewall-cmd --permanent --add-p…

(深度学习快速入门)第三章第三节2:深度学习必备组件之损失函数和激活函数

文章目录一:损失函数(1)均方误差损失(MSE)(2)交叉熵损失(Cross Entropy)二:激活函数(1)tanh(2)ReLU&#xff0…