Synchronize 锁对象、类、原理分析

1.Synchronized 用法

1.类锁

锁静态方法,Class,只有一个线程可以获得,只有一份,不管是否是同一个实例

2.对象锁

普通对象,this,如果多个线程,用到的实例时一个,并且锁也是该实例,那么只有一个线程可以获得,如果多个线程都是使用的自己的实例,那么久不存在竞争

3. 示例

package com.pgf.juc.synchronizedT;

import java.util.Date;

/**
 * @Auther: pgf
 * @Date: 2020/3/4 0004
 * @Description: com.pgf.juc
 * @ToDo: synchronized 锁类、方法、块
 * @version: 1.0
 */
public class SynchronizedTest {
          
   

    /*对象锁*/
    public synchronized void synMethod() throws InterruptedException {
          
   
        System.out.println(Thread.currentThread().getName() +" i m synchronized method");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName() +new Date());
    }

    /*类锁*/
    public synchronized static void synStaticMethod() throws InterruptedException {
          
   
        System.out.println(Thread.currentThread().getName() +" i m synchronized static method");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName() +new Date());
    }

    /*类锁*/
    public void synClass() throws InterruptedException {
          
   
        synchronized (SynchronizedTest.class){
          
   
            System.out.println(Thread.currentThread().getName() +" i m synchronized Class");
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() +new Date());
        }
    }

    public static void main(String[] args) {
          
   
        SynchronizedTest synchronizedTest = new SynchronizedTest();
        for (int i = 0; i < 3; i++) {
          
   
            new Thread(new Runnable() {
          
   
                @Override
                public void run() {
          
   
                    try {
          
   
                        new SynchronizedTest().synClass();
                        //new SynchronizedTest().synMethod();
                        //SynchronizedTest.synStaticMethod();
                    } catch (InterruptedException e) {
          
   
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

}

4.锁Class结果

2.Synchronized 原理分析

1.对象在内存中的结构分析

package com.pgf.obj.anaysis;

import org.openjdk.jol.info.ClassLayout;

/**
 * @Auther: pgf
 * @Date: 2020/3/5 0005
 * @Description: com.pgf.obj.anaysis 64位的jvm
 * @ToDo:
 * @version: 1.0
 */
public class ObjHeadAnaysis {
          
   
    public static void main(String[] args) {
          
   
        User user= new User();
        /*获取hashCode 类信息才有值,否则为*/
        System.out.println(user.hashCode());
        System.out.println(Integer.toBinaryString(user.hashCode()));
        /*查看user的内存布局信息*/
        System.out.println(ClassLayout.parseInstance(user).toPrintable());
}
class User {
          
   
    private String name;
    private int age;
    private boolean sex;
}
偏向锁标识位 锁标识位 锁状态 存储内容 0 01 未锁定 hash code(31),年龄(4) 1 01 偏向锁 线程ID(54),时间戳(2),年龄(4) 无 00 轻量级锁 栈中锁记录的指针(64) 无 10 重量级锁 monitor的指针(64) 无 11 GC标记 空,不需要记录信息

下图有错误,第一个8位,第1位没用,2-5位是gc年龄,6位 标志是否有锁,7-8锁状态 OFFSET:偏移地址 SIZE:单位字节 TYPE DESCRIPTION: 信息描述 object header 对象头 jvm是默认开启了指针压缩,所以每个信息占用的字节更小了 字节对齐,64位虚拟机默认兑现过的长度是8的整数倍

object header 对象头有两部分组成,对象运行时的数据、类元素数据的指针(确定对象是那个类的实例)

经验分享 程序员 微信小程序 职场和发展