synchronized的使用方式有两种
1 对一个对象进行加锁
synchronized(O){ //代码 }
2 对一个方法加锁
public synchornized void func(){ //代码 }
其实无论是对一个对象进行加锁还是对一个方法进行加锁,实际上,都是对对象进行加锁。
java中一个对象由三部分组成=>
1 对象头=>markwork(hashCode(只有在调用后才会有),GC分代年龄,锁信息),class指针,如果是数组的话还会有一个数组的长度
2 实例数据=》存放对象字段的数据
3 填充数据=》为了保证一个对象所占用的字节数是8的倍数,提高执行效率
4 如果对象是数组的话对象头
偏向锁的概念一直不太好理解,偏向锁其实没有上锁,只是将线程指针加到对象头中,在更改的时候原理是cas。之所要偏向锁,是因为大部分情况下都是一个进程在操作,当有竞争的时候,需要将锁升级(一般升级为轻量级锁,如果加了await就直接进入重量级锁,在升为轻量级锁的时候,偏向的线程也要和其他的线程重新进行cas操作来获取锁),但是在升级的时候会让偏向的这个线程先获取锁,偏向锁的意义就是为了让偏向的线程先获取锁。
偏向锁产生的条件?=》只有偏向锁已启动(即偏向锁的标志位为1)的对象才能产生偏向锁,如果没有则直接进入轻量级锁。
对象如何启动偏向?=》只有在jvm启动一段时间(一般4秒钟)后创建的对象jvm才会给该对象头的偏向锁标志位设置为1。
代码示例:
public static void main(String[] args) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { Object o = new Object(); synchronized (o){ System.out.println(ClassLayout.parseInstance(o).toPrintable()); } }).start(); }
原文:https://www.cnblogs.com/Tony100/p/12922458.html