java 锁详解

news2024/11/28 8:39:46

         死锁有四个条件

1. 互斥性  某个锁单元只能被某个运算单元占用

2. 不可以剥夺  线程获取某个资源, 这个资源不可以被其他资源剥夺, 只能自己释放, 

3. 请求并保持  请求别的资源的同时却保持占有某个资源

4. 形成循环链路  

        一般锁都有互斥性, 读锁没有互斥性. 一般的锁都不可以被剥夺的, 除非自己主动释放, 解决办法是当获取其他锁超过一定时间, 释放自己占有的锁资源 , 一般的死锁都是请求并保持, 一个持有A资源, 去请求B资源, 另一个线程持有B资源, 却是请求A资源. 一般解决办法是对资源进行排序, 按顺序获取资源. 形成循环链路, java1.7hashMap头插法, 就有可能形成环形链路. 

java死锁的例子

public static void main(String[] args) {

        Object A = new Object();
        Object B = new Object();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                synchronized (A) {
                    Thread.sleep(2000);
                    System.out.println("线程甲获取A锁");
                    synchronized (B) {
                        System.out.println("线程甲获取B锁");
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                synchronized (B) {
                    Thread.sleep(2000);
                    System.out.println("线程乙获取B锁");
                    synchronized (A) {
                        System.out.println("线程乙获取A锁");
                    }
                }
            }
        }).start();
    }

 使用visualVM查看线程情况, 发现线程死锁提醒

查看线程dump, 发现线程Thread-0和Thread-1有BLOCK字段, 表示线程被阻塞. 

- waiting to lock <0x0000000702024290> (a java.lang.Object)
    - locked <0x00000007020242a0> (a java.lang.Object)

线程1等待锁资源<0x0000000702024290>, 自己占用锁资源<0x00000007020242a0>

    - waiting to lock <0x00000007020242a0> (a java.lang.Object)
    - locked <0x0000000702024290> (a java.lang.Object)
 线程0等待锁资源<0x00000007020242a0>, 自己占用锁资源<0x0000000702024290>

所以综上所述, 这两个线程互相争夺对方的资源而形成死锁. 

使用jconsole, 线程窗口, 点击检测死锁.

 Thread-0死锁锁定Object, 显示object的地址 

C:\software\jdk1.8.0_101\bin>jps -l
20704 com.jesse.log.LockTest
26576 org/netbeans/Main
5156 org.netbeans.lib.profiler.server.ProfilerServer
1304 org.jetbrains.jps.cmdline.Launcher
24232 sun.tools.jps.Jps
26312
25516 sun.tools.jconsole.JConsole

使用jps -l 显示java 线程的pid和类路径

C:\software\jdk1.8.0_101\bin>jstack -l 20704
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x000000001a3033d8 (object 0x000000070201c1c0, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000001a300d58 (object 0x000000070201c1d0, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.jesse.log.LockTest$2.run(LockTest.java:37)
        - waiting to lock <0x000000070201c1c0> (a java.lang.Object)
        - locked <0x000000070201c1d0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)
"Thread-0":
        at com.jesse.log.LockTest$1.run(LockTest.java:24)
        - waiting to lock <0x000000070201c1d0> (a java.lang.Object)
        - locked <0x000000070201c1c0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

Thread-0等待锁监视器 0x000000001a300d58 (object 0x000000070201c1d0, a java.lang.Object),

但是Thread-0却持有锁<0x000000070201c1c0>

Thread-1等待锁监视器0x000000001a3033d8 (object 0x000000070201c1c0, a java.lang.Object),

但是Thread-1却持有锁<0x000000070201c1d0>

所以就形成死锁. 

 使用jmc, 启动jmx, 点击线程面板, 选中死锁检测

java中有悲观锁和乐观锁

悲观锁

有synchronized修饰的方法和代码块

还有基于AQS的锁

ReentrantLock 支持公平非公平, 支持可重入, 支持中断 

ReentrantReadWriteLock 可以生成读写锁, 读读不互斥, 某段代码可以多个线程同时执行的, 可以用读锁.

Semaphore 信号量, 可以用做限流

countDownLatch  可以用做等待一堆任务完成才开始其他任务. 

java的乐观锁是通过CAS实现的. 

CAS主要过程是先获取某个地址的值, 在修改的时候, 会去比较和之前获取的值是否相等, 如果相等就修改成新值, 如果不相等, 不做处理. 这种情况下会遇到ABA问题, 就是线程1获取某个变量的值为A, 刚好线程2修改了这个变量为B, 然后有很无聊把它改回A. 这时候切换到线程1, 发现变量的和之前的值相等, 所以做了更新操作. 解决这个问题的方法时加一个版本. 每修改一次, 版本都变一次, 最后线程1虽然获得变量和之前获取的一样, 但是版本不一致, 所以不做处理

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

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

相关文章

视觉系统相关的网站

1.视觉系统设计 视觉系统设计网址&#xff1a;http://www.vision-systems-china.com/emag/emag.asp

宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution

宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution 容器参数 docker-compose.yml 的 dns我也设置&#xff0c;按理来说应该可以访问&#xff0c;然而就是不断的按在地上摩擦 web:build: .restart: alwaysports:- "6699:80"dns:- 114.11…

公司内部重要文件如何加密防止泄露?

现如今&#xff0c;是互联网时代&#xff0c;数据安全在互联网时代中的数据安全岌岌可危&#xff0c;企业中&#xff0c;都会拥有终端&#xff0c;终端中每天都要处理文档&#xff0c;文件&#xff0c;表格&#xff0c;产生一系列的数据问题等&#xff0c;这个时候就要先企业中…

Windows OS CMD 常用工具 の 命令合集

# First Of All 每次想要修改环境变量都要按部就班点开系统属性、高级系统设置、环境变量。这种操作实在是太繁琐了&#xff0c;对于我一个懒人来讲实在是 忍无可忍 。如果可以使用 WINR 或 CMD 直接打开系统内的一些工具&#xff0c;是不是就可以节省很多时间&#xff1b;是不…

自己写的程序创建开机自启

1、winr 2、输入shell:startup 3、把需要启动的程序快捷方式放在此文件夹下面即可

最详细的编译paddleOcrGPU C++版本指南(包含遇到坑的解决办法)

前言&#xff1a; 我是之前编译过调用CPU的paddleOcr的C版本&#xff0c;其实CPU版本与GPU版本并无太大不同&#xff0c;只不过是调用库版本的不同&#xff0c;然后原项目中几个相关参数改一下就可以&#xff0c;但是在这个过程中我找不到关于编译paddleOcrGPU C版本的详细教程…

【Docker】Consul的容器服务更新与发现

目录 一、Consul二、什么是服务注册与发现1.2什么是consul1.3consul提供的一些关键特性 二、Consul部署2.1环境配置2.2Consul服务器配置1. 建立 Consul 服务2. 查看集群信息3. 通过 http api 获取集群信息 2.3 registrator服务器配置1. 安装 Gliderlabs/Registrator2. 测试服务…

如何设置Axure中文版 Mac系统下axurerp10怎么设置成中文

有许多小伙伴肯定想知道axure rp 10怎么转换为中文版&#xff0c;接下来就为大家带来最详细的汉化教程&#xff0c;大家可以根据教程一步一步操作&#xff0c;保证可以汉化成功&#xff01; 准备工作 安装好axurerp10 axurerp10汉化包 百度网盘链接: 百度网盘 请输入提取码 …

【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值

最近想用c做一个小游戏&#xff0c;游戏的主要内容是利用键盘控制一个飞机躲避和击落屏幕顶部随机掉落敌方炮弹&#xff0c;飞机被敌方炮弹击中则减掉一条命&#xff0c;飞机也可以发射炮弹反击&#xff0c;每击落一个敌方炮弹&#xff0c;则有相应积分。 游戏的思路就是利用w…

Docker配置阿里云容器镜像加速

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

目录操作在C语言中:一个全面的指南

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

7.26 Qt

用QT制作一个登陆界面 运行代码 login.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //信息调试类&#xff0c;用于输出 #include <QIcon> //图标类头文件 #include <QPushButton&…

更新合集 | 七月功能上新记

点击链接了解详情 七月来临&#xff0c;正式开启 2023 下半年的新征途&#xff01;这个盛夏&#xff0c;腾讯云 CODING 上线了微信扫码注册、微信通知、Go 制品管理等重点能力&#xff0c;为企业及团队研发管理带来更多便利&#xff01;以下是 CODING 新功能速递&#xff0c;快…

一文搞定IP地址

IP编址系列文章&#xff08;上&#xff09; 目录 一&#xff0c;什么是IP地址&#xff1f; 二&#xff0c;IP地址的表示方式 问题&#xff1a;计算机能识别二进制&#xff1f;十进制&#xff1f;十六进制&#xff1f; 三&#xff0c;二进制如何转换为十进制呢&#xff1f; …

如何准备远程开发环境

准备一台有root权限的服务器 创建用于开发的子用户 使用adduser命令创建新用户: sudo adduser newuser为新用户添加sudo权限,编辑sudoers文件: sudo visudo在文件中添加: newuser ALL(ALL:ALL) ALL将新用户添加到docker用户组: sudo usermod -aG docker newuser改权限 ch…

Java 聊天程序案例

单线程版本&#xff1a; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner;//服务端 public class Server {public static void main(String…

HikariCP连接池

HikariCP连接池 HikariCP连接池是高性能的JDBC连接池&#xff0c;官网标注的三大特点&#xff1a;快速、简单、可靠&#xff0c;性能优于其他连接池。 官网详细地说明了HikariCP所做的一些优化&#xff0c;总结如下&#xff1a; 字节码精简&#xff1a;优化代码&#xff0c;直…

领跑人机协同时代!实在智能与EFCIO携手举办AI沙龙,推动企业数字化转型

GPT翻开了AGI&#xff08;通用人工智能&#xff09;领域的新篇章&#xff0c;也开启了各行各业的新时代。毫不夸张地说&#xff0c;进入大模型时代&#xff0c;所有的应用都值得被重写一遍。同时&#xff0c;企业也需要积极采纳新技术和创新模式&#xff0c;以应对竞争压力和不…

MURF2080CT/MURF2080CTR-ASEMI快恢复对管

编辑&#xff1a;ll MURF2080CT/MURF2080CTR-ASEMI快恢复对管 型号&#xff1a;MURF2080CT/MURF2080CTR 品牌&#xff1a;ASEMI 芯片个数&#xff1a;2 芯片尺寸&#xff1a;102MIL*2 封装&#xff1a;TO-220F 恢复时间&#xff1a;50ns 工作温度&#xff1a;-50C~150C…

代码随想录day28

46. 全排列 思路&#xff1a;这道题首先是一个排列问题&#xff0c;排列问题是讲究顺序的&#xff0c;例如[1,2]和[2,1]是两个不一样的排列&#xff0c;这里的1我们会有重复使用到&#xff0c;但是&#xff0c;在每一个排列中&#xff0c;每一个元素只能使用一次。所以需要一个…