一.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) {
}
}
  • 因为s1s2的创建都使用的是直接赋值,此时的hello会创建在常量池中,实际上s1s2都指向的是同一个对象,被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);

最新文章

  1. HTML5 摇一摇加强版之一次失败的探索
  2. Android手机刷recovery
  3. golang开发环境配置及Beego框架安装
  4. 使用MultipartEntity进行post请求的默认MIME类型
  5. ThrottleAttribute
  6. jquery 中的 return false 不起作用
  7. 大数的乘法(C++)
  8. 【ZZ】 DShader之位移贴图(Displacement Mapping)
  9. 5.6 a、b交换
  10. CodeIgniter学习一:基础知识
  11. 每日冲刺报告--Day2
  12. .NET+MySql 踩坑1
  13. Thread 详解
  14. 潭州课堂25班:Ph201805201 爬虫高级 第七课 sclapy 框架 爬前程网 (课堂笔)
  15. C# 反射总结 获取 命名空间 类名 方法名
  16. PHP-redis api 中文说明(转)
  17. STC-51开发板-单片机控制数码管&amp;按键&amp;点阵综合操作
  18. Notes of Daily Scrum Meeting(11.4)
  19. The POSIX API/nss/nscd
  20. ElasticSearch 基础概念学习(未完)

热门文章

  1. Vue API 3模板语法 ,指令
  2. Activiti工作流引擎使用详解(一)
  3. 用oracle中的Row_Number实现分页
  4. 最基础的SSM框架整合篇
  5. CPU测试工具
  6. python内置模块(一)
  7. [BUUCTF]PWN——[HarekazeCTF2019]baby_rop2
  8. 工期设定(Project)
  9. Python基础入门(6)- 面向对象编程
  10. CF1166A Silent Classroom 题解