synchronized对象锁和类锁

一、什么是对象锁和类锁

顾名思义 对象锁可以锁住同一对象下synchronized修饰的方法,但不会影响其他对象。synchronized修饰普通方法就为对象锁。

类锁static synchronized修饰一个方法,当一个线程在执行该方法时,其他任何线程用任何对象调用static  synchronized修饰的方法都需要等待。

二、对象锁例子

class Data {public synchronized void synchronizedHello() {try {TimeUnit.MILLISECONDS.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName() + "-----hello");}public synchronized void synchronizedGood(){System.out.println(Thread.currentThread().getName() + "-----good");}public  void nice(){System.out.println(Thread.currentThread().getName() + "-----nice");}
}
public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {Data data = new Data();Data data1 = new Data();new Thread(data::synchronizedHello, "a").start();TimeUnit.MILLISECONDS.sleep(200);new Thread(data::synchronizedGood, "b").start();new Thread(data::nice, "c").start();new Thread(data1::synchronizedGood, "d").start();}
}

输出结果:

c-----nice
d-----good
a-----hello
b-----good

介绍: 主线程中创建了四个线程分别为a,b,c,d他们分别调用data对象的synchronizedHello,synchronizedGood,nice方法。调用synchronizedHello主线程睡眠0.2秒。

synchronizedHello方法加锁切会使线程睡眠2秒钟

synchronizedGood方法仅加锁

nice方法不加锁

结果分析:c-----nice最先打印说明nice方法不受a线程synchronizedHello方法的睡眠2秒影响,正常异步执行完成。说明对象锁不加synchronized的方法不受锁的影响。

d-----good第二个打印同样不受a线程synchronizedHello方法的睡眠2秒影响。说明对象锁只能锁住自己对象的synchronized修饰的方法。

b-----good最后打印是受到了a线程synchronizedHello方法的睡眠2秒影响。说明synchronized修饰的方法并非独立,会收到其他synchronized修饰的方法的影响。

 三、类锁例子

class Data {public static synchronized void synchronizedHello() {try {TimeUnit.MILLISECONDS.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName() + "-----hello");}public static synchronized void synchronizedGood(){System.out.println(Thread.currentThread().getName() + "-----good");}public  void nice(){System.out.println(Thread.currentThread().getName() + "-----nice");}
}
public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {Data data = new Data();Data data1 = new Data();new Thread(() -> data.synchronizedHello(), "a").start();TimeUnit.MILLISECONDS.sleep(200);new Thread(() -> data.synchronizedGood(), "b").start();new Thread(() -> data1.synchronizedGood(), "d").start();new Thread(data::nice, "c").start();}
}

输出结果:

c-----nice
a-----hello
d-----good
b-----good

介绍:方法 synchronizedHello,synchronizedGood都加了static修饰

结果分析:先打印c----nice因为nice方法没加锁

d-----good,b-----good在a-----hello后打印说明其他任何线程用任何对象调用static  synchronized修饰的方法都需要等待

如果删除synchronizedGood的static修饰则输出结果为:

b-----good
d-----good
c-----nice
a-----hello

 结果说明:类锁的方法并没有锁住对象锁修饰的方法。

四、结论

对象锁的锁对象是对象本身即this而类锁的锁对象是类名.class索引其不是同一把锁,互不干扰。开发中遇到需要加锁的地方应当尽量使用对象锁而不是类锁。

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

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

相关文章

软件测试之 接口测试 Postman使用

接口测试 URL HTTP协议 HTTP 请求部分 HTTP响应部分 Postman使用 界面介绍 这里 注意 如果你无法访问 那么 captchaImage这个打错了,给的资料中是错误的地址 https://kdtx-test.itheima.net/api/captchaImage登录接口 科大天下 第一个接口的登录设置 https://kd…

使用map类型的参数在mapper.xml中使用案例

使用map类型的参数在mapper.xml中使用案例 简介:在常见的开发中,对于参数的装载一般使用map类型方式,这样可以避免创建很多参数实体类,不管嵌套多层的数据参数都可以通过map拿取,对于嵌套多层的map,我们需…

如何在Java中使用异常处理机制

如何在Java中使用异常处理机制在Java中,异常处理是一种在程序运行时识别和响应错误情况的机制。它允许程序在出现异常时继续执行,而不是崩溃。Java异常处理机制的核心概念包括try、catch、finally、throw和throws关键字。下面详细介绍这些概念&#xff0…

已知哈夫曼节点个数,求哈夫曼字符编码数

哈夫曼编码(Huffman Coding)是一种用于无损数据压缩的嫡编码(权编码)算法。 在哈夫曼树中,每个叶子节点都代表一个字符,而节点的权重通常代表字符的频率。在哈夫曼编码中,每个字符都会被赋予一个二进制编码。为了获得这些编码,我…

云渲染动画300帧需要多久呢?瑞云渲染为你揭秘

在动画制作过程中,渲染的速度非常关键。对于一个项目需要渲染的300帧来说,由于硬件的限制,许多公司的设备可能无法快速完成这项任务。此时,借助云渲染服务的强大计算能力,可以显著减少完成时间,从而提速整个…

独孤思维:副业拉新排名第一很牛吗

01 30年河东,30年河西。 我从来不觉得,自己星球拉新第一,或者小报童直播一场卖80份有多牛。 因为比我牛比的,比我拉新多的大佬多了去了。 这个5月,比我潜在爆发的牛人也有很多。 过去的历史成绩,代表当…

【Java基础】初识正则表达式

正则表达式只适用于字符串 匹配matches 实际使用的是String类中定义的方法boolean matches(String regex) public static void piPei( ){String regex"[1][356789]\\d{9}";boolean boo"14838384388".matches(regex);System.out.println(boo); }验证qq号…

QtConcurrent::run操作界面ui的注意事项(2)

前面的“QtConcurrent::run操作界面ui的注意事项(1)”,末尾说了跨线程的问题,引出了Qt千好万好,就是跨线程不好。下面是认为的最简单的解决办法:使用QMetaObject::invokeMethod(相比较信号-槽&a…

构建无服务器数仓(二)Apache DolphinScheduler 集成以及 LOB 粒度资源消费分析

引言 在数据驱动的世界中,企业正在寻求可靠且高性能的解决方案来管理其不断增长的数据需求。本系列博客从一个重视数据安全和合规性的 B2C 金融科技客户的角度来讨论云上云下混合部署的情况下如何利用亚马逊云科技云原生服务、开源社区产品以及第三方工具构建无服务…

18 分页:介绍

目录 简单例子 页表存在哪里 列表中究竟有什么 分页:也很慢 内存追踪 小结 在解决大多数空间管理问题上面,操作系统有两种方法: 第一种就是将空间分割成不同长度的分片,类似于虚拟内存管理中的分段,但是这个方法…

电商平台自动回复脚本制作的流程!

随着电子商务的快速发展,电商平台在日常运营中面临着大量的客户咨询和服务需求,为了提高客户服务效率和质量,许多电商平台采用了自动回复脚本,以快速响应客户问题并提供准确的信息。 本文将详细介绍电商平台自动回复脚本制作的流…

证券期货市场失信记录代表什么?

证券期货市场失信记录是指参与证券期货市场的个人或机构在交易、信息披露、内部控制等方面存在违法违规失信行为的记录。 这些失信行为包括但不限于未履行承诺、拒不履行已达成的纠纷调解协议、未按期兑付本息、未按约定履行担保责任、实施犯罪行为,以及在融资融券…

SpringBoot MybatisPlus 配置动态表名多数据源

需求 业务场景: 日志、交易流水表或者其他数据量大的表,通过日期进行了水平分表,需要通过日期参数,动态的查询数据。 实现思路:利用MybatisPlus的动态表名插件DynamicTableNameInnerInterceptor ,实现Sql执行时&#…

Matten:视频生成与Mamba-Attention

Matten:视频生成与Mamba-Attention 摘要IntroductionRelated WorkMethodology Matten: Video Generation with Mamba-Attention 摘要 在本文中,作者介绍了Matten,一种具有Mamba-Attention架构的尖端潜在扩散模型,用于视频生成。在极小的计算…

带EXCEL附件邮件发送相关代码

1.查看生成的邮件 2.1 非面向对象的方式(demo直接copy即可) ​ REPORT Z12. DATA: IT_DOCUMENT_DATA TYPE SODOCCHGI1,IT_CONTENT_TEXT TYPE STANDARD TABLE OF SOLISTI1 WITH HEADER LINE,IT_PACKING_LIST TYPE TABLE OF SOPCKLSTI1 WITH HEADER LIN…

《他强由他强,清风拂山岗;他横由他横,明月照大江》之三

常见的设计模式 1.策略模式 使用场景 通俗来说,策略模式就像是让你有一个策略的工具箱,在不同的情况下选择最合适的策略来解决问题。 使用场景通常包括以下一些: 多重条件判断语句: 当一个操作包含大量的条件判断语句,并且这些分支具有不同的行为时,可以使用策略模式来…

docker runc升级1.1.12

上传runc-1.1.12制品至中控机 874e970eaa932a97de9888344ae08f24 runc.arm64 将所有节点的runc文件备份 所有节点(包括master+node) vim host [all] 10.1.0.183 ansible_password=Bigdata@Ksyun123 ansible_user=root ansible_port=22 10.1.0.249 ansible_password=Bigdata…

关于 vs2019 c++ 20规范,STL 库提供的标准分配器 alloctor 及其 traits 及涉及分配器交换的全局函数 _Pocs

(1) 我们写 c 代码,使用 STL 库中的模板,很少自己写对象的分配器。用 STL 中的分配器也够用。研究 STL 中的分配器也可以为咱们自己写分配器提供参考。 咱们会遇到这样的场景,例如交换两个容器对象: list a ,b ; a .swap (b) ; 这…

自建XXL-JOB调度平台教程

一、XXL-JOB简介 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。它支持通过Web界面进行管理调度任务,包括任务的增删改查、执行状态监控等。同时,XXL-JOB提供了Java、Spring Boot等多种接入方式&am…

C++中向量的操作vector

在C中&#xff0c;std::vector 是一个非常有用的动态数组容器&#xff0c;它允许你在运行时动态添加或删除元素&#xff0c;并且提供了许多方法来操作这些元素。下面是一些常见的 std::vector 操作&#xff1a; 创建一个 vector&#xff1a; #include <vector> std::vec…