1.锁范围:
    1.修饰代码块:锁就是关键字后的对象
    2.修饰实例方法:锁就是当前对象
    3.修饰静态方法:锁就是当前类.class
    2.底层实现
    jdk早期 重量级锁->找操作系统调度

    3.锁升级
    无锁
    偏向锁:锁对象的mark word记录线程ID,一旦发生竞争,升级
    自旋锁:旋转10次仍然获取不到,升级,用户态,占用CPU,(执行时间短,线程数少)
    重量级锁:OS调度,内核态,不占用CPU,在等待队列,(执行时间长,线程数多)
    4.同步方法与非同步方法一起调用容易产生脏读问题,比如写数据加锁,读数据不加锁,读到的数据不一定准确
    5.可重入,如果不支持可重入,会导致死锁
    6.异常可以释放锁,导致其他线程可以正常获取锁
    7.synchronized保持原子性,可见性
    8.synchronized 不能锁定String常量、 基础数据类型包装类。锁定String容易导致死锁或者重入。包装类对象容易发生变化。
    9.synchronized优化
    1.锁细化
    10.对象头