Synchronized保证三大特性

synchronized能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

synchronized (锁对象) {
    // 受保护资源
}

 一、synchronized保证原子性

案例演示:5个线程各执行1000次 i++;

 

对number++;增加同步代码块后,保证同一时间只有一个线程操作number++;。就不会出现安全问题。

总结:

synchronized保证原子性的原理,synchronized保证只有一个线程拿到锁,能够进入同步代码块。

 二、synchronized保证可见性

案例演示:一个线程根据boolean类型的标记flag, while循环,另一个线程改变这个flag变量的值,另一个线程并不会停止循环。

 

 

 synchronized保证可见性的原理,执行synchronized时,会对应lock原子操作会刷新工作内存中共享变量的值

三、synchronized保证有序性

3.1 为什么要重排序

为了提高程序的执行效率,编译器和CPU会对程序中代码进行重排序。

3.2 as-if-serial语义

as-if-serial语义的意思是:不管编译器和CPU如何重排序,必须保证在单线程情况下程序的结果是正确的。

以下数据有依赖关系,不能重排序。

写后读:

int a = 1;
int b = a;

写后写:

int a = 1;
int a = 2;

读后写:

int a = 1;
int b = a;
int a = 2;

编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。但是,如果操作之间不存在数据依赖关系,这些操作就可能被编译器和处理器重排序。

int a = 1;
int b = 2;
int c = a + b;

上面3个操作的数据依赖关系如图所示:

如上图所示a和c之间存在数据依赖关系,同时b和c之间也存在数据依赖关系。因此在最终执行的指令序列中,c不能被重排序到a和b的前面。

但a和b之间没有数据依赖关系,编译器和处理器可以重排序a和b之间的执行顺序。

下图是该程序的两种执行顺序。

可以这样:
int a = 1;
int b = 2;
int c = a + b;

也可以重排序这样:
int b = 2;
int a = 1;
int c = a + b;

3.3 使用synchronized保证有序性

 

总结:

synchronized后,虽然进行了重排序,保证只有一个线程会进入同步代码块,也能保证有序性。

synchronized保证有序性的原理,我们加synchronized后,依然会发生重排序,只不过,我们有同步代码块,可以保证只有一个线程执行同步代码中的代码。保证有序性

视频教程

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值