【java多线程】synchronized和volatile
2024-09-05 02:36:49
文章目录
一.synchronized
1.synchronized使用的方法
- 可以直接修饰代码块
synchronized (this) {
//代码块
}
- 调用可能出现并发问题的方法
synchronized (this) {
method();
}
- 修饰方法
public synchronized void method() {
//...
}
2.注意
当synchronized修饰方法时:
- 非静态方法中,synchronized锁当前对象:
this
- 静态方法中,synchronized锁的是当前类的字节码对象
User.class
3.不要以字符串作为锁的对象
- 有如下代码
String s1 = "hello";
String s2 = "hello";
void m1() {
synchronized (s1) {
}
}
void m2() {
synchronized (s2) {
}
}
- 因为
s1
和s2
的创建都使用的是直接赋值,此时的hello
会创建在常量池中,实际上s1
,s2
都指向的是同一个对象,被s1、s2引用。 - 所以,此时的
synchronized (s1)
和synchronized (s2)
实际上锁的都是同一个对象。 - 因此,使用
synchronized
锁的时候最好不要锁字符串类型。 - 如果非要锁字符串,那么使用
new String ("hello")
的方法来创建字符串,因为这样创建出来的字符串就是两个堆内存中的对象了。
4.synchronized
锁的是什么?
synchronized
锁的是堆内存中new
出来的对象,而不是栈中的引用。
二、volatile
1.引出问题
两个线程操作同一个主存数据时,会先将主存中的数据复制到自己的内存区域,将数据修改后,再写回主存。
两线程同时复制到自己内存后:
- 线程1将数据修改
a=1
后,写回主存 - main线程很忙,一直在进行while(true) 循环,没有时间再去主存中读取新的数据,所以main线程缓存中的数据还是
a=0
- 为了解决这个问题,就引出了
volatile
2. volatile
使用方法
- 直接将
volatile
关键字加在要操作的数据上
private volatile int a = 0;
3.volatile原理
- 当
线程1
将数据修改后,会通知main线程
:“你的数据已经过期了” - 此时
main线程
会从主存中重新读取
新的数据 - 这也就是volatile三个特性的-
保证可见性
4.volatile三大特性
- 保证可见性
- 不保证原子性
- 禁止指令重排
三、volatile和synchronized的区别
1.区别
- volatile是轻量级的,synchronized是是重量级的
- volatile保证内存可见性,而不保证原子性(解决此问题的办法:就是使用原子数据)
- synchronized既保证内存可见性,也保证原子性
2.解决原子性问题–原子型数据类型
- 在
java.util.concurrent.atomic
包下,有基本数据类型对应的原子型的数据类型,类似于基本数据类型的包装类型。
3.让对象类型数据具有原子型
- 还是在
java.util.concurrent.atomic
包下,有一个类,可以使对象类型的数据具有原子性:AtomicReference
//创建两个对象
User zhangsan = new User("zhangsan");
User sili = new User("sili");
//创建原子操作对象
AtomicReference<User> atomicReference = new AtomicReference<User>();
//比较并交换
boolean b = atomicReference.compareAndSet(zhangsan, sili);
System.out.println(b);
最新文章
- HTML5 摇一摇加强版之一次失败的探索
- Android手机刷recovery
- golang开发环境配置及Beego框架安装
- 使用MultipartEntity进行post请求的默认MIME类型
- ThrottleAttribute
- jquery 中的 return false 不起作用
- 大数的乘法(C++)
- 【ZZ】 DShader之位移贴图(Displacement Mapping)
- 5.6 a、b交换
- CodeIgniter学习一:基础知识
- 每日冲刺报告--Day2
- .NET+MySql 踩坑1
- Thread 详解
- 潭州课堂25班:Ph201805201 爬虫高级 第七课 sclapy 框架 爬前程网 (课堂笔)
- C# 反射总结 获取 命名空间 类名 方法名
- PHP-redis api 中文说明(转)
- STC-51开发板-单片机控制数码管&;按键&;点阵综合操作
- Notes of Daily Scrum Meeting(11.4)
- The POSIX API/nss/nscd
- ElasticSearch 基础概念学习(未完)