分布式与高并发-2-Synchronized

1、实例锁

1.1、代码

public class SynchronizedTest {
    
    
    synchronized void demo1(){
    
    
        //等价于synchronized(this) 是对这个类的实例进行加锁
        try {
    
    
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":"+DateTimeUtils.getCurrDateTime());
    }

    //与demo1等价
    void demo2(){
    
    
        synchronized (this){
    
    
            try {
    
    
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+DateTimeUtils.getCurrDateTime());
        }
    }
    
    public static void main(String[] args) {
    
    
        SynchronizedTest test1=new SynchronizedTest();
        //实例锁
        new Thread(()->test1.demo1(),"demo1").start();
        new Thread(()->test1.demo1(),"demo2").start();


        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        SynchronizedTest test2=new SynchronizedTest();
        SynchronizedTest test3=new SynchronizedTest();

        new Thread(()->test2.demo1(),"demo3").start();
        new Thread(()->test3.demo1(),"demo4").start();
    }
}

1.2、执行结果

在这里插入图片描述

1.3、结果分析

  1. demo1和demo2线程都是对test1实例进行抢占锁,存在互斥性,所以存在阻塞
  2. demo3和demo4是两个实例 test2和test3,所以不存在阻塞
  3. 只针对当前对象实例加锁,test1、test2、test3存在三个锁,因为这是三个实例

2、静态方法=类锁=类对象锁

2.1、代码

public class SynchronizedTest {
    
    
    synchronized static void demo1(){
    
    
        //等价于synchronized(this) 是对这个类的实例进行加锁
        try {
    
    
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":"+DateTimeUtils.getCurrDateTime());
    }

    //与demo1等价
    void demo2(){
    
    
        synchronized (SynchronizedTest.class){
    
    
            try {
    
    
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+DateTimeUtils.getCurrDateTime());
        }
    }

    public static void main(String[] args) {
    
    
        SynchronizedTest test1=new SynchronizedTest();
        //类锁
        new Thread(()->test1.demo1(),"demo1").start();
        new Thread(()->test1.demo1(),"demo2").start();
        try {
    
    
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        SynchronizedTest test2=new SynchronizedTest();
        SynchronizedTest test3=new SynchronizedTest();
        //类锁
        new Thread(()->test2.demo1(),"demo3").start();
        new Thread(()->test3.demo1(),"demo4").start();
    }
}

2.2、运行结果

在这里插入图片描述

2.3、结果分析

  1. 加在类上的锁,不管是不是一个实例,都会存在互斥性,进行锁竞争
  2. 类锁和对象锁 体现在互斥的范围
  3. 类锁:针对所有的对象都互斥

3、代码块锁

其实就是锁对象的应用范围

4、锁升级

4.1、 互斥锁的本质-> 共享资源

4.2、锁升级过程:由于加锁一定会带来性能开销,所以JDK1.6后做了锁优化,锁逐渐升级,ThreadA持有了偏向锁,ThreadB来抢占偏向锁,若在偏向锁内部的处理机制中,ThreadB不能抢占成功获得锁,则会升级到轻量级锁,如果轻量级锁中还没有获取到,则ThreadB在重量级锁中进行阻塞;

ThreadA
没有获得锁的线程怎么处理
ThreadA
偏向锁
轻量级锁
重量级锁
执行
释放之后
BLOCK状态排队
ThreadB
4.2.1、优化的目的?

在ThreadB线程阻塞前,获得锁;在不加锁的情况下解决线程安全问题

4.2.2、性能开销?

是线程的阻塞带来性能开销

4.3、偏向锁过程

  1. 线程1进入代码块后,获得偏向锁,并且线程1将同步块的互斥标记修改
  2. 在有线程1获得偏向锁的阶段,线程2访问代码块,会先检查对象头是否存储里线程2,如果没有则尝试CAS替换Mark-Word,如果替换不成功,则撤销原有偏向锁,然后进行锁升级(轻量级锁);如果替换成功则线程2获得偏向锁
    2.1、扩展:
    什么时候CAS替换成功,由线程2获得偏向锁呢?
    答:
    1》线程1已经执行结束
    2》已经升级到轻量级锁+
    3》已经是全局安全点,没有指令在操作
    什么时候开启轻量级锁?
    答:
    1》如果现成本身就存在竞争则不要开始轻量级锁->因为轻量级锁本身就是一种优化,目的是提升数据在没有竞争的时候的效率
    2》轻量级锁默认是关闭的
没有
成功
没有
不成功
线程1
访问同步块
检查对象头中是否存储了线程1
CAS替换mark-word
将对象头Mark-word中的线程id指向自己
执行同步体
暂停线程
解锁将线程ID设为空
去除线程1上之前添加的标记
线程1添加一个标记
线程2
访问代码块
检查对象头中是否存储了线程2
CAS尝试替换mark-word
撤销偏向锁

猜你喜欢

转载自blog.csdn.net/qq_28500837/article/details/109667749