线程安全之同步锁

2023-09-13 08:01:48

一、synchronize

synchronize 的锁标记存在对象头里面

锁升级从上到下

锁升级的本质是作者对线程安全和性能的平衡

无锁——加锁

当只有A线程时:

偏向锁    单线程,不存在竞争,该线程获取锁后,不再需要抢占

当线程B加入,开始抢占锁时,锁首先升级为轻量级锁,进行自旋抢占,

轻量级锁

        避免线程阻塞,通过自旋锁实现(cas),自旋是消耗cpu的,

        自旋次数少时cas的消耗比唤醒锁的性能开销要小

        1.7开始有自适应自旋,性能安全和性能的平衡

当B自旋次数内没有抢占到锁,升级为重量级锁,

重量级锁

        有锁,把阻塞线程加入到等待队列

synchronized锁的作用范围:

        synchronized 锁的本质是锁的对象,如下面代码,

public class SynchronizeDemo {

    /* *
     * @Description:修饰实例方法
     */
    public synchronized void m1(){

    }

    /* *
     * @Description:修饰代码块(当前对象)
     */
    public void m2(){
        synchronized (this){

        }
    }

    /* *
     * @Description:修饰代码块(类对象)
     */
    public void m3(){
        synchronized (SynchronizeDemo.class){

        }
    }

    /* *
     * @Description:修饰静态方法
     */
    public static synchronized void m4(){

    }

    public static void main(String[] args) {
        SynchronizeDemo sd1 = new SynchronizeDemo ();
        SynchronizeDemo sd2 = new SynchronizeDemo ();

        new Thread(()->{        //线程A
            sd1.m1 ();
//            sd1.m2 ();
//            sd1.m3 ();
//            sd1.m4 ();
        }).start ();
        new Thread(()->{        //线程B
            sd1.m1 ();
//            sd1.m2 ();
//            sd1.m3 ();
//            sd1.m4 ();
        }).start ();
        new Thread(()->{      //线程C
            sd2.m1 ();
//            sd2.m2 ();
//            sd2.m3 ();
//            sd2.m4 ();
        }).start ();


    }


}

当调用m1方法时:

        线程A和线程B之间有锁竞争,和线程C之间没有锁的竞争。

当调用m2方法时:

        线程A和线程B之间有锁竞争,和线程C之间没有锁的竞争。

当调用m3方法时:

        线程A和线程B之间有锁竞争,和线程C之间也有锁的竞争。

当调用m4方法时:

        线程A和线程B之间有锁竞争,和线程C之间也有锁的竞争。

CAS

pompareAndSwap(old,expect,update)

old:内存中的对象

expect:比较值

update:更新的值

返回值为true /false

  • 作者:**飞星**
  • 原文链接:https://blog.csdn.net/qq_38774360/article/details/121879188
    更新时间:2023-09-13 08:01:48