JUC——8锁问题

文章目录

    • 问题一和问题二:
    • 问题三:
    • 问题四:
    • 问题五和问题六:
    • 问题七和问题八:
    • 总结

八锁现象是在多线程编程中经常遇到的一种情况,指的是在使用synchronized关键字进行同步时可能出现的不同的执行顺序。下面对问题一到问题八进行总结:

问题一和问题二:

  • 两个线程分别调用Phone类的senMesg()和call()方法。
  • 根据synchronized关键字的特性,锁的是方法的调用者,这里锁的是phone对象。
  • 在标准情况下,两个线程交替执行,先输出发短信,然后输出打电话。
  • 如果senMesg()方法延迟了4秒,那么先输出发短信,再输出打电话。
public class Test1 {public static void main(String[] args) {Phone phone = new Phone();new Thread(()->{phone.senMesg();},"A").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{phone.call();},"B").start();}
}
class Phone{public synchronized void senMesg(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发短信");}public synchronized void call(){System.out.println("打电话");}
}

这两个问题涉及同一个对象的同步方法之间的互相调用。当线程执行一个对象的同步方法时,它就持有了这个对象的锁。当它需要再次调用这个对象的另一个同步方法时,如果这个方法也是同步的,那么这个线程就可以直接进入该方法,而无需重新获取锁。这就是“可重入锁”的体现。
在这里插入图片描述

问题三:

  • 添加了一个普通方法hello(),与同步方法senMesg()同时执行。
  • hello()方法不受锁的影响,所以先输出hello,然后输出发短信。
public class Test2 {public static void main(String[] args) {Phone1 phone = new Phone1();new Thread(()->{phone.senMesg();},"A").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{phone.hello();},"B").start();}
}
class Phone1{public synchronized void senMesg(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发短信");}public synchronized void call(){System.out.println("打电话");}public void hello(){System.out.println("hello");}
}

这个问题涉及父子类继承关系中使用同步方法。父类中的同步方法在被子类继承后,子类同样可以使用这个同步方法,并且可以在这个同步方法中调用父类的同步方法,这也是“可重入锁”的体现。

问题四:

  • 使用两个不同的Phone对象phone1和phone2,分别执行senMesg()和call()方法。
  • 两个对象的锁是不同的,所以先输出发短信,然后输出打电话。
public class Test3 {public static void main(String[] args) {Phone2 phone1 = new Phone2();Phone2 phone2 = new Phone2();new Thread(()->{phone1.senMesg();},"A").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{phone2.call();},"B").start();}
}
class Phone2{public synchronized void senMesg(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发短信");}public synchronized void call(){System.out.println("打电话");}
}

这个问题涉及不同对象的同步方法之间的互相调用。当线程执行一个对象的同步方法时,它就持有了这个对象的锁。如果它需要调用另一个对象的同步方法,那么这个线程就需要获取另一个对象的锁才能进入该方法,因此这两个同步方法之间没有“可重入锁”的关系。
在这里插入图片描述

问题五和问题六:

  • 两个静态同步方法,只有一个Phone对象phone1。
  • 根据synchronized关键字的特性,锁的是类模板,即Phone类。
  • 所以无论是调用senMesg()还是call()方法,都会先输出发短信,然后输出打电话。
public class Test4 {public static void main(String[] args) {Phone3 phone1 = new Phone3();new Thread(()->{phone1.senMesg();},"A").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{phone1.call();},"B").start();}
}
class Phone3{public static synchronized void senMesg(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发短信");}public static synchronized void call(){System.out.println("打电话");}
}

这两个问题涉及静态同步方法和非静态同步方法之间的互相调用。静态同步方法持有的是类锁,而非静态同步方法持有的是对象锁,因此它们持有的锁是不同的,没有“可重入锁”的关系。
在这里插入图片描述

问题七和问题八:

  • 一个静态同步方法senMesg()和一个普通同步方法call(),执行顺序为先打电话再发短信。
  • 两个Phone对象phone1和phone2,分别执行静态同步方法和普通同步方法。
  • 静态同步方法锁的是类模板,普通同步方法锁的是调用者对象。
  • 所以无论是phone1还是phone2,都会先输出打电话,然后输出发短信。
public class Test5 {public static void main(String[] args) {Phone4 phone1 = new Phone4();Phone4 phone2 = new Phone4();new Thread(()->{phone1.senMesg();},"A").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{phone2.call();},"B").start();}
}
class Phone4{public static synchronized void senMesg(){try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发短信");}public synchronized void call(){System.out.println("打电话");}
}

总结

synchronized关键字用于方法或代码块时,它可以用来实现对象级别的锁和类级别的锁。

  1. 对象级别锁:

    • synchronized用于非静态方法时,锁对象是调用该方法的实例对象。即每个对象实例都有自己的锁。
    • synchronized用于代码块时,锁对象可以是任意的Java对象。通常情况下,我们使用某个共享资源作为锁对象。
    • 无论是方法级别的锁还是代码块级别的锁,同一时间只能有一个线程获得锁并执行同步代码,其他线程需要等待锁释放。
  2. 类级别锁:

    • synchronized用于静态方法时,锁对象是当前方法所属的类对象(Class对象)。
    • 类级别锁是针对整个类的所有对象实例生效的,不同实例之间共享这个锁。
    • 同一时间只能有一个线程获得类级别锁并执行同步代码,其他线程需要等待锁释放。

总结:

  • 对象级别的锁是基于对象实例的,每个对象实例有自己的锁,不同实例之间互不影响。
  • 类级别的锁是基于类对象的,所有类的实例共享同一个锁。
  • synchronized关键字通过获取锁来保证同一时间只有一个线程可以执行同步代码块或方法。
  • 锁的作用是保护共享资源,避免多个线程同时访问导致的数据竞争和并发问题。

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

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

相关文章

C++ 类的静态成员

我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。 静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时&#xff0…

JNPF低代码引擎到底是什么?

最近听说一款可以免费部署本地进行试用的低代码引擎,源码上支持100%源码,提供的功能和技术支持比较完善。借助这篇篇幅我们了解下JNPF到底是什么? JNPF开发平台是一款PaaS服务为核心的零代码开发平台,平台提供了多租户账号管理、主…

Linux中的定时任务(案例:定时备份和清空)

前言 Linux中的定时任务(案例:定时备份和清空) crontab 命令 Linux crontab 是用来定期执行程序的命令, 当安装完成操作系统之后,默认便会启动此任务调度命令。crond 命令每分钟会定期检查是否有要执行的工作,如果有…

数据结构:二分图

参考链接: https://zhuanlan.zhihu.com/p/96229700 Bipartite Graph Definition G (U, V, E)all the edges are between U and V.No edge between two vertices in U.No edge between two vertices in V. Bipartite Matching G (U, V…

适配器模式介绍

目录 一、适配器模式介绍 1.1 适配器模式定义 1.2 适配器模式原理 1.2.1 适配器模式类图 1.2.2 模式角色说明 二、适配器模式的应用 2.1 类适配器模式 2.1.1 需求说明 2.1.2 需求实现 2.1.2.1 类图 2.1.2.2 具体实现 2.1.2.2.1 SDCard接口 2.1.2.2.2 SDCardImpl实现…

Intra-Inter Camera Similarity for Unsupervised Person Re-Identification

一、研究背景 1.由于人工标注样本昂贵,许多工作致力于通过以下手段进行无监督行人重识别: 域自适应:对齐源域、目标域特征分布 风格转换:使用生成对抗网络转换源域图片风格,并维持源域图片身份 伪标签生成:…

java.lang.UnsupportedOperationException: null 其一解决办法

文章目录 前言一、错误回顾1.详细信息2.代码详情 二、解决方案1.错误原因2.解决方案1.使用 new ObjectMapper() new TypeReference<List>(){}2.使用 SerializerFeature.WriteMapNullValue.getMask() 总结 前言 当我们远程调用传递泛型集合&#xff0c;如 List<?>…

【重明】机器视觉QT/C++实现工业相机二次开发框架

工业相机二次开发是机器视觉行业必不可少的技能之一。 而如何实现一个框架&#xff0c;能够兼容所有工业相机二次开发&#xff0c;从而支持多种类型的工业相机&#xff0c;就是机器视觉行业的进阶技能了。 重明工业相机二次开发项目就是在实现相机二开框架的基础上&#xff0c…

解决方案:reactNative通过webview跳转微信智能客服空白webview页面

在reactNative中使用webview跳转微信智能客服&#xff0c;功能正常&#xff0c;从微信退回到App时&#xff0c;会有一个空白的webview页面&#xff0c;在使用感觉上不是那么的顺滑。解决这个可以在webview中使用onLoadEnd方法来解决这个问题 在react-native-webview中onLoadEn…

计算机视觉开发工程师怎么考?报考难度大吗?证书含金量高吗?

为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求&#xff0c;深入实施人才强国战略和创新驱动发展战略&#xff0c;加强全国数字化人才队伍建设&#xff0c;持续推进人工智能专业人员…

Android 事件机制探讨(1)

事件的传递主要有三个方法&#xff1a;dispatchTouchEvent(事件分发)、onInterceptTouchEvent(事件拦截)、onTouchEvent(事件消费)。如下图&#xff1a; 仔细看的话&#xff0c;图分为3层&#xff0c;从上往下依次是Activity、ViewGroup、View事件从左上角那个白色箭头开始&…

法规更新美国玩具标准ASTM F963-17有更新,最新标准为ASTM F963-23

美国材料试验协会 (ASTM)在10月13日发布了新的玩具安全标准&#xff1a;ASTM F963-23&#xff0c;ASTM F963-17美国联邦法规16 CFR 1250还在使用当中&#xff0c;出口美国的玩具的厂商要引起重视。 ASTM F963-17是什么标准&#xff1f; ASTM F963-17是美国玩具检测标准&#…

Java基于SpringBoot+Vue的大学生入学审核系统的设计与开发,附源码、数据库

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

NFS网络共享存储服务技术攻略

目录 一.NFS 1.定义 2.特点 3.原理 二.服务端NFS配置文件 1.主配置文件 2.文件格式 3.相关命令 三.实验&#xff1a;NFS共享存储服务配置 1.服务端安装nfs-utils和rpcbind软件包 2.服务端新建共享目录给权限 3.服务端修改配置文件/etc/exports 4.服务端关闭防火墙…

C#开源免费的Blazor图表库

前言 今天分享一款基于ApexCharts.js封装的、C#开源免费的Blazor图表库&#xff1a;Blazor-ApexCharts。 10款值得推荐的Blazor UI组件库 全面的ASP.NET Core Blazor简介和快速入门 ApexCharts.js介绍 ApexCharts.js开源地址&#xff1a;GitHub - apexcharts/apexcharts.js:…

python.24.1.16函数

python自带函数 自定义函数 参数的使用

Java工具类——json字符串格式化处理

在我们拿到一团未经格式化的json字符串时&#xff0c;非常不方便查看&#xff0c;比如这样 {"APP_HEAD": {"TOTAL_NUM": "-1","PGUP_OR_PGDN": "0"},"SYS_HEAD": {"RET": [{"RET_CODE": &qu…

如何做用户分层和标签体系

“活动作了一场接一场&#xff0c;简直要累死了&#xff0c;拉进来的客户也没有多少&#xff0c;投入产出完全不成比例&#xff0c;怎么办&#xff1f;“ “有那么多注册用户&#xff0c;但是GMV怎么才这么点&#xff0c;他们怎么不买啊&#xff0c;难道都是羊毛党&#xff1f;…

el-select中多选回显数据后没法重新选择和更改

<el-form-item label"展示内容" prop"videoId"><el-select class"modal-input" multiple v-model"form.videoId"><el-optionclass"modal-input"v-for"(item) in videoIdTypes":key"item.id&q…

2019年认证杯SPSSPRO杯数学建模D题(第二阶段)5G时代引发的道路规划革命全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 D题 5G时代引发的道路规划革命 原题再现&#xff1a; 忙着回家或上班的司机们都知道交通堵塞既浪费时间又浪费燃料&#xff0c;甚至有的时候会带来情绪上的巨大影响&#xff0c;引发一系列的交通问题。据报道&#xff0c;每年交通拥堵使得美国…