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; }
下图有错误,第一个8位,第1位没用,2-5位是gc年龄,6位 标志是否有锁,7-8锁状态 OFFSET:偏移地址 SIZE:单位字节 TYPE DESCRIPTION: 信息描述 object header 对象头 jvm是默认开启了指针压缩,所以每个信息占用的字节更小了 字节对齐,64位虚拟机默认兑现过的长度是8的整数倍
object header 对象头有两部分组成,对象运行时的数据、类元素数据的指针(确定对象是那个类的实例)