synchronized锁原理、对象头

package com.scma.synchronized_test;

/*
 * 关键字synchronized 原理
 * */
public class synchronizedTest implements Runnable {
    public static int num = 0;

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            num++;
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<100;i++){
            new Thread(new synchronizedTest()).start();
        }
        try {
            Thread.sleep(2000);  //等所有线程执行++ 操作完成
        } catch ( Exception e) {

        }
        System.out.println(num);
    }
}

预期是100*10000 = 100000 但是结果是:95159

很自然而然的想法就是每一个线程依次去读写这个共享变量,这样就不会有任何数据安全的问题

Synchronized用的位置可以有这些使用场景:

在这里插入图片描述

底层原理
执行同步代码块后首先要先执行monitorenter指令,退出的时候monitorexit指令

使用Synchronized进行同步,其关键就是必须要对对象的监视器monitor进行获取,
当线程获取monitor后才能继续往下执行,否则就只能等待。而这个获取的过程是互斥的,
即同一时刻只有一个线程能够获取到monitor。

Synchronized先天具有重入性。每个对象拥有一个计数器,当线程获取该对象锁后,计数器就会加一,释放锁后就会将计数器减一。

hapens-before(待细扣)

如果A happens-before B,则A的执行结果对B可见

2. 什么是CAS

使用锁时,线程获取锁是一种悲观锁策略,即假设每一次执行临界区代码都会产生冲突,所以当前线程获取到锁的时候同时也会阻塞其他线程获取该锁。而CAS操作(又称为无锁操作)是一种乐观锁策略,它假设所有线程访问共享资源的时候不会出现冲突,既然不会出现冲突自然而然就不会阻塞其他线程的操作。因此,线程就不会出现阻塞停顿的状态。那么,如果出现冲突了怎么办?无锁操作是使用CAS(compare and swap)又叫做比较交换来鉴别线程是否出现冲突,出现冲突就重试当前操作直到没有冲突为止。

当多个线程使用CAS操作一个变量,只有一个线程会成功,并成功更新,其余会失败。失败的线程会重新尝试,当然也可以选择挂起线程。

2.1 Synchronized VS(对比) CAS

在存在线程竞争的情况下会出现线程阻塞和唤醒锁带来的性能问题,因为这是一种互斥同步(阻塞同步)。而CAS并不是武断的间线程挂起,当CAS操作失败后会进行一定的尝试,而非进行耗时的挂起唤醒的操作,因此也叫做非阻塞同步。这是两者主要的区别。

2.2 CAS 应用场景

在J.U.C包中利用CAS实现类有很多,可以说是支撑起整个concurrency包的实现,在Lock实现中会有CAS改变state变量,在atomic包中的实现类也几乎都是用CAS实现。

2.3 CAS的问题

1、ABA问题

如一个旧值A变为了成B,然后再变成A,刚好在做CAS时检查发现旧值并没有变化依然为A,但是实际上的确发生了变化。解决方案可以沿袭数据库中常用的乐观锁方式,添加一个版本号可以解决。原来的变化路径A->B->A就变成了1A->2B->3C。在java 1.5后的atomic包中提供了AtomicStampedReference来解决ABA问题,解决思路就是这样的。

2、自旋时间过长

使用CAS时非阻塞同步,也就是说不会将线程挂起,会自旋(无非就是一个死循环)进行下一次尝试,如果这里自旋时间过长对性能是很大的消耗。

3、只能保证一个共享变量的原子操作

当对一个共享变量执行操作时CAS能保证其原子性,如果对多个共享变量进行操作,CAS就不能保证其原子性。有一个解决方案是利用对象整合多个共享变量,即一个类中的成员变量就是这几个共享变量。然后将这个对象做CAS操作就可以保证其原子性。atomic中提供了AtomicReference来保证引用对象之间的原子性。

3. Java对象头

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码头薯条Pro

本文能帮到阁下,在下很开心!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值