Java并发编程- Synchronized原理

本文详细解析了Java中的Synchronized关键字,包括其在不同JDK版本中的实现变化,从无锁到偏向锁、轻量级锁再到重量级锁的过程,并介绍了锁的状态及其实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java并发编程- Synchronized原理

在jdk.1.6之前是重量级锁,jdk1.6之后对synchronzied的关键字的优化之后,引入了偏向锁,轻量级锁。

1.先来看synchronzied使用的基础:

static  A a = new A();

//普通同步方法
public synchronized void test(){
    System.out.println("锁的是当前对象实例");
}
//静态同步方法
public static synchronized void test1(){
    System.out.println("锁的是当前类的Class对象");
}
//同步方法块
public   void test2(){
    synchronized (a){
        System.out.println("锁的是括号里配置的对象");
    }
}

2. synchronzied使用的锁在哪呢?存在对象头里,

整个对象存储情况,运行代码查看结果分析:

public class A {

    private boolean b;
}
public class Test {
    static  A a = new A();
    public static void main(String[] args) {
        System.out.println(VM.current().details());
        System.out.println(ClassLayout.parseInstance(a).toPrintable());
    }
}

运行结果分析:

分析:对象一共16B,其中12B是对象头,1B是对象实例数据,3B是字节对齐

对象的长度

长度内容说明
12B对象头存储信息,hashcode,年代信息等。
1B对象实例数据存储对象的实例数据
3B字节对齐 

对象头12B存储哪些内容呢?64位的VM

可以从openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html 官网上看到,存储的内容是mark word 和klass word

java对象头的长度

长度内容说明
8Bmark word存储着锁的信息,hashcode,gc信息等等
4Bklass word 指向对象的元数据

java对象头的结构

无锁的对象头如下:

第一个字节的前8位存储着,分代年龄4个bit,锁的标识2个bit,是否偏向1个bit,和没有使用的1个bit。

其他的7个字节存储着hashcode信息。

锁状态56bit4bit1bit是否偏向锁2bit锁的标识
无锁对象hashcode对象分代年龄001

我们知道对象的状态一共五种状态:无锁,偏向锁,轻量级锁,重量级锁,gc标记的锁。

3. 偏向锁

概念:同一个线程多次获取同一把锁。(只有一个线程调用同步块)

代码:

public class Test {
    static  A a ;
    public static void main(String[] args) {
        Thread.sleep(5000);//jvm 延时启动偏向锁,是默认4s之后开启,可以设置关闭延时。因为启动的时候就使用偏向锁,比较消耗性能,升级锁比较费时间。

        System.out.println(VM.current().details());
        a = new A();
        System.out.println(ClassLayout.parseInstance(a).toPrintable());
        syn();
            System.out.println(ClassLayout.parseInstance(a).toPrintable());
    }
    public static  synchronized  void syn(){
        System.out.println("演示偏向锁-----------");
    }
}

输出结果:

演示偏向锁-----------

 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           80 22 01 f8 (10000000 00100010 00000001 11111000) (-134143360)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

分析结果:程序只有一个线程main调用syn方法,因此是偏向锁,也可以使用-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0禁用延时。-XX:+TraceClassLoading (跟踪加载)

4. 轻量级锁:线程交替运行,无竞争。

public class Test {
    static  A a ;
    public static void main(String[] args) throws InterruptedException {
      //  System.out.println(VM.current().details());
        a = new A();
        System.out.println(ClassLayout.parseInstance(a).toPrintable());
        syn();
        System.out.println(ClassLayout.parseInstance(a).toPrintable());

    }
    public static    void syn(){
        synchronized (a){
            out.println("lock ing");
            System.out.println(ClassLayout.parseInstance(a).toPrintable());
        }
    }
}

运行结果:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

lock ing
com.luban.wf.A object internals:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           a0 f5 e7 02 (10100000 11110101 11100111 00000010) (48756128)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

com.luban.wf.A object internals:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total


Process finished with exit code 0
 

分析结果:lock ing 输出的10100000 轻量级锁。

 

5. 重量级锁:

public class Test2 {
    static  A a ;

    public static void main(String[] args) throws InterruptedException {
        a = new A();
        System.out.println("before lock");
        out.println(ClassLayout.parseInstance(a).toPrintable());//轻量锁

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                synchronized (a){

                    synchronized (a){
                        System.out.println("before wait");
                        out.println(ClassLayout.parseInstance(a).toPrintable());//轻量锁
                        try {
                            a.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("after wait");
                        out.println(ClassLayout.parseInstance(a).toPrintable());//重量级锁
                    }
                }
            }
        });

        t1.start();

        Thread.sleep(5000);
        synchronized (a){
            a.notifyAll();//唤醒线程t1
        }

    }


}

运行结果:


before lock
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

before wait
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           a0 f2 7b 1c (10100000 11110010 01111011 00011100) (477885088)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

after wait
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           da d7 e2 19 (11011010 11010111 11100010 00011001) (434296794)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     1   boolean A.b                                       false
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total


Process finished with exit code 0
 

运行结果分析:after wait  的为11011010 重量级锁

 

 

 

6. 偏向锁的批量撤销:

 

 

 

7. 轻量级锁的膨胀过程:

 

 

 

 

 

 

 

 

8.总结:

锁有哪几种:公平锁和非公平锁(线程获取锁的机会不是均匀的)

工作当中怎样选择锁:

Synchronized 是有sun公司实现的 jvm内部调用操作系统实现的

1.是个非公平锁,

2.使用简单,

3.经过优化了,偏向锁,轻量级锁,重量级锁

lock jdk实现的:

1.是个公平锁,

2.需要手动释放锁

3.如果要实现高级功能,可以使用

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值