synchronized锁升级流程(偏向锁、轻量级锁-锁自旋、重量级锁)

本文介绍了synchronized锁在多线程并发场景下的作用,探讨了锁诞生的背景,包括原子性、可见性和有序性问题。文章详细讲解了synchronized的演进,从jdk1.6之前的重量级锁到之后的偏向锁、轻量级锁,分析了锁的优化策略,如自旋锁和自适应自旋。文中还详细描述了锁对象的Mark Word结构及其在不同锁状态下的变化,并给出了查看对象头信息的方法。最后总结了synchronized的性能提升,强调了偏向锁和轻量级锁在无或轻度竞争情况下的高效性,以及如何在竞争加剧时升级为重量级锁。
摘要由CSDN通过智能技术生成

一、锁诞生的背景:

      咱们说的锁,不是每家每户的门锁,咱们说的锁是多线程并发场景下,或者分布式集群下,对共享变量的修改,需要增加锁的机制,保证数据操作的安全性,影响数据的安全性包含以下几个方面:

      1)原子性:

            常见的面试问题   i++是否线程安全??

             针对 i++,cpu需要分三步操作:

            A、读取i

            B 、累加运算

            C、写回缓存

            这样看i++并不是一个原子操作,所以是不安全的。

      2)可见性:

            可见性问题,也是比较常见,A线程对共享变量的修改,对B线程不可知,导致数据一致性问题。

      3)有序性:

            有序性,是指CPU指令执行层面,指令执行的流程可能根咱们的程序不太一致。

      日常除了上面说的多线程并发层面的锁,还有经常遇到以下类型的锁:

      1)日常在Mysql数据库中,innodb存储引擎,采用行锁,防止多个更新请求对同一条记录的修改操作;

      2)在集群模式下,单台应用的软硬件优化已经达到极致,为了支撑更多的并发,采用水平扩展,大家应用集群;在集群模式下,多个节点对共享数据的访问,就会有新的概念“分布式锁”,可以用redis,zk,MySQL行锁等等方式实现。

      这是目前大家经常遇到的锁的概念,今天我们重点介绍单节点,多线程并发场景下,数据安全问题;

 

二、初识synchronized:

以jdk1.6版本作为分水岭,在之前没有偏向锁,轻量级锁的概念,synchronized是重量级锁,我们先从用法上来认识synchronized

package com.jason.juc;

public class TestMain {

    public int counter=0;

    public void increCounter()
    {
        counter=counter+1;
    }

    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    public static void main(String[] args) throws InterruptedException {
       final TestMain  testMain=new TestMain();
        Thread[]  threads=new Thread[2];

        for(int i=0;i<threads.length;i++)
        {
            threads[i]=new Thread("thread"+i){
                @Override
                public void run() {
                      for(int j=0;j<10000;j++)
                      {
                          testMain.increCounter();
                      }
                }
            };
            threads[i].start();
        }
        threads[0].join();
        threads[1].join();
        System.out.println("-----main=="+testMain.getCounter());
    }
}

理想情况下,运行结果是20000,但是实际情况并非如此:

接下来,我们来看一下synchronized的日常用法:

大致用法可以分为两块:

1)修饰方法

2)修饰代码块

//    public synchronized void increCounter()//修饰非静态方法,表示锁的是当前对象
//    {
//        counter=counter+1;
//    }

//    public static synchronized
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

石头城程序猿

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值