搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
AllinToyou
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
Git配合idea的使用_idea与git
2
Objective-C runtime机制(1)——基本数据结构:objc_object & objc_class_objective-c runtime objc_object isa
3
hive.log日志摘录_hiveconf of name hive.metastore.event.db.notificat
4
GEM5教程-Garnet_gem5 garnet 介绍
5
ElementUI及ElementUI Plus Axure RP高保真交互元件库及模板库_elementui原件能做高保真吗?
6
C语言从头到尾完整遍历升序链表程序_c语言 单链表升序
7
Promise难懂?一篇文章让你轻松驾驭_promise也不太懂
8
CNN网络的故障诊断(轴承的多故障类型分类+Python代码)_python故障诊断卷积神经网络代码
9
pg数据库安装_pgsql安装
10
Windows本地搭建开源的stable-diffusion-webui用于AIGC文生图
当前位置:
article
> 正文
Java synchronized 对象锁与类锁的区别、同步代码块与同步方法的区别 详解_对象锁与类锁能否同步
作者:AllinToyou | 2024-04-13 00:09:37
赞
踩
对象锁与类锁能否同步
java 内置锁 : 每个 java对象 都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。java 内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当 线程A 尝试去获得 线程B 持有的内置锁时,线程A 必须等待或者阻塞,直到 线程B 释放这个锁,如果B线程不释放这个锁,那么 A线程 将永远等待下去
java 对象锁和类锁 : java 的 对象锁 和 类锁 在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的 class对象上的。类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
类的 非静态方法锁 和 内置锁是同一把锁,也就是都是 对象锁。因此当对象执行到 同步代码块 时这个对象的另外一个线程由于无法获得对象锁因此无法执行这个对象的所有使用 synchronized 修饰的非静态方法
public class TestSynchronized1 {
public void test1() {
synchronized (this) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
}
public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
public static void main(String[] args) {
final TestSynchronized1 myt2 = new TestSynchronized1();
Thread test1 = new Thread(myt2::test1, "test1");
Thread test2 = new Thread(myt2::test2, "test2");
test1.start();
test2.start();
// 输出 :
// test1 : 4
// test1 : 3
// test1 : 2
// test1 : 1
// test1 : 0
// test2 : 4
// test2 : 3
// test2 : 2
// test2 : 1
// test2 : 0
}
}
public class TestSynchronized4 {
class Inner {
private void m4t1() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
private synchronized void m4t2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
}
private void m4t1(Inner inner) {
synchronized (inner) {
// 使用对象锁
inner.m4t1();
}
}
private void m4t2(Inner inner) {
inner.m4t2();
}
public static void main(String[] args) {
final TestSynchronized4 myt3 = new TestSynchronized4();
final Inner inner = myt3.new Inner();
Thread t1 = new Thread(() -> myt3.m4t1(inner), "t1");
Thread t2 = new Thread(() -> myt3.m4t2(inner), "t2");
t1.start();
t2.start();
// 输出 :
// t1 : Inner.m4t1()=4
// t1 : Inner.m4t1()=3
// t1 : Inner.m4t1()=2
// t1 : Inner.m4t1()=1
// t1 : Inner.m4t1()=0
// t2 : Inner.m4t2()=4
// t2 : Inner.m4t2()=3
// t2 : Inner.m4t2()=2
// t2 : Inner.m4t2()=1
// t2 : Inner.m4t2()=0
}
}
静态方法锁 就是 类锁
public class TestSynchronized2 {
public void test1() {
synchronized (TestSynchronized2.class) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
}
public static synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
public static void main(String[] args) {
final TestSynchronized2 myt2 = new TestSynchronized2();
Thread test1 = new Thread(myt2::test1, "test1");
Thread test2 = new Thread(TestSynchronized2::test2, "test2");
test1.start();
test2.start();
// 输出 :
// test1 : 4
// test1 : 3
// test1 : 2
// test1 : 1
// test1 : 0
// test2 : 4
// test2 : 3
// test2 : 2
// test2 : 1
// test2 : 0
}
}
类锁 和 对象锁不是通一把锁,相互之间互不干扰
public class TestSynchronized3 {
public synchronized void test1() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
public static synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
public static void main(String[] args) {
final TestSynchronized3 myt2 = new TestSynchronized3();
Thread test1 = new Thread(myt2::test1, "test1");
Thread test2 = new Thread(TestSynchronized3::test2, "test2");
test1.start();
test2.start();
// 输出 :
// test1 : 4
// test2 : 4
// test2 : 3
// test1 : 3
// test2 : 2
// test1 : 2
// test2 : 1
// test1 : 1
// test1 : 0
// test2 : 0
}
}
此处会先输出 showA.. showC.. 等待 3秒后再输出 showB..,可以使用 synchronized 代码块或方法只有获取到响应的锁之后才能执行相应的方法
public class TestSynchronized5 {
public synchronized void showA() {
System.out.println("showA..");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void showB() {
synchronized (this) {
System.out.println("showB..");
}
}
public void showC() {
String s = "1";
synchronized (s) {
System.out.println("showC..");
}
}
public static void main(String[] args) {
final TestSynchronized5 sy = new TestSynchronized5();
new Thread(sy::showA).start();
new Thread(sy::showB).start();
new Thread(sy::showC).start();
// 输出 :
// showA..
// showC..
// showB..
}
}
1> 当两个并发线程访问同一个对象 object 中的这个 synchronized(this) 同步代码块时,一个时间内只能有一个线程得到执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块
2> 然而,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,另一个线程仍然可以访问该 object 中的非synchronized(this)同步代码块
3> 尤其关键的是,当一个线程访问object的一个 synchronized(this) 同步代码块时,其他线程对 object 中所有其它 synchronized(this) 同步代码块 或 synchronized 修饰的非静态方法 的访问将被阻塞
4> 对象锁和类锁可以同时获得,即两种方法可以同时运行,互不影响
5> 一种锁方法只能运行同时运行一个,同种其他的锁方法暂时阻塞,普通方法的运行不受限制
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/AllinToyou/article/detail/413334
推荐阅读
article
全网最全讲解
Stable
Diffusion
原理
,
小白也能看懂!速来!!!_
stable
diffu...
如果不解释无分类器引导(Classifier-Free Guidance
,
CFG)
,
这篇文章将是不完整的
,
这是AI艺术家...
赞
踩
article
齿轮
故障
诊断
数据
集
分享(包括轴承和
齿轮
)
_
齿轮
故障
数据
集
...
齿轮
故障
诊断
数据
集
分享(包括轴承和
齿轮
)
_
齿轮
故障
数据
集
齿轮
故障
数据
集
...
赞
踩
article
uniapp
开发小
程序
项目...
uniapp
开发小
程序
项目_
uniapp
开发小
程序
uniapp
开发小
程序
...
赞
踩
article
【
数据结构
】
队列
的
实现
及
循环
队列
的
实现
详解(c语言)_1.建立
一个
循环
队列
,输出
队头
与
队尾
元素
、
元素
...
通过下图可以看到定义了两个结构体,第
一个
结构就是我们常用的节点,而第二结构体中的成员可以理解为head指针是用来指向
队头
...
赞
踩
article
循环
队列
的实现...
用顺序表实现
循环
队列
_
循环
队列
的实现
循环
队列
的实现 该题目来自力扣,具体要求如下: ...
赞
踩
article
基于jsp+
mysql
+
Spring
+
Spring
MVC+mybatis的ssm生鲜
超市
进销存管理系...
目前
超市
越来越多,越来越普及,如何高效的管理经营
超市
才是成功的关键,其中对于中小型
超市
来说,在降低成本的前提下使用最有效...
赞
踩
article
基于
java
web+
mysql
的ssm+
maven
超市
进销存
管理系统
(
java
+ssm+jsp+bo...
超市
进销存
管理系统
,主要分为管理员与员工两种角色:管理员主要功能模块有: 进货管理:进货信息、退货信息;库存管理:库存信...
赞
踩
article
动态
规划
(DP)之入门学习-
数字
三角形
_
数字
三角形
问题
...
数字
三角形
案例题目描述 Description下图给出了一个
数字
三角形
,请编写一个程序,计算从顶至底的某处的一条路径,使...
赞
踩
article
【AI视野·今日CV
计算机
视觉
论文速览 第280期】
Mon
, 1 Jan 2024_multisc...
AI视野·今日CS.CV
计算机
视觉
论文速览
Mon
, 1 Jan 2024Totally 46 papersmultis...
赞
踩
article
Go
语言
mac
环境
搭建详解...
Go
1.11版本之后无需手动配置
环境
变量,使用go mod 管理项目,也不需要非得把项目放到GOPATH指定目录下,你可...
赞
踩
article
Kafka
高级(3)-
监控
工具
Kafka
-
eagle
介绍...
Kafka
高级(3)-
监控
工具
Kafka
-
eagle
介绍
Kafka
-Eagle简介在开发工作中,当业务前提不复杂时,可以...
赞
踩
article
获取
微信
小
程序
源码_
获取
微信
小
程序
源代码...
获取
微信
源码_
获取
微信
小
程序
源代码
获取
微信
小
程序
源代码 一、使用adb连接手机
获取
小
程序
源码 ...
赞
踩
article
小
甲鱼
零
基础
入门
学习
python
--
课后
作业
(更新至第19讲,持续更新)_小
甲鱼
零
基础
入门
pytho...
本章内容:小
甲鱼
零
基础
入门
学习
python
--
课后
作业
1、
基础
部分的
作业
2、函数部分的
作业
3、字典、集合、文件部分
作业
4...
赞
踩
article
【
C++
】
string
模拟
实现...
【
C++
】
string
模拟
实现 ...
赞
踩
article
3月
面试
字节
一面
就
被刷
,
9月二战
字节
终于上岸
,
准备
了
小
半年
,
这我要
个
28K应该也不过分吧?_
比较
两
个
...
终于二战上岸了
,
二战
字节
也并不是说非
字节
不可
,
只是觉得心里憋着一口气
,
这
就
导致我当时有其他
比较
好
的
offer
,
我也没有去...
赞
踩
article
一份
好
的
软件测试
人员
简历
是
什么样子
的
?_
软件测试
简历
csdn
...
我做了近10年
的
测试开发,先告诉大家
的
是
一份
好
的
简历
离不给大家分享一下如何打造
一份
高质量
的
简历
!_
软件测试
简历
csdn
...
赞
踩
article
NLP
学习
路线
指南总结_
nlp
学习
路径...
通过以上
学习
路线
,你将能够逐步掌握
NLP
的核心技术和应用,并在实践中不断提升自己的能力和水平。记得在
学习
过程中保持对最新...
赞
踩
article
JavaSE
-
06
笔记
【
数组
(
+2024新
)
】...
/对自定义的引用类型的
数组
进行排序,不能直接调用Arrays.sort public static void main(...
赞
踩
article
使用
python
实现CNN-
GRU
故障诊断
_
python
gru
...
这只是一个简单示例,您可能需要根据您的数据集的特点进行必要的调整,例如输入信号的形状、类别数量和标签格式等。如需更详细或...
赞
踩
article
源代码
到
可执行程序
的过程详解:预
编译
、
编译
、
汇编
、链接_如何得
到
.
i
文件
...
(1)首先是将.c源
文件
和.h头
文件
经过预
编译
(cpp是预
编译
器),得
到
.
i
文件
,主要是进行的一些替换工作;(2)将.
i
...
赞
踩
相关标签
stable diffusion
人工智能
AI作画
ai绘画
深度学习
大数据
uni-app
小程序
数据结构
c语言
链表
java
计算机毕业设计
mysql
maven
动态规划
DP
计算机视觉
CV
视觉
StableDiffusion
扩散模型
NERF
golang
开发语言