码迷,mamicode.com
首页 > 其他好文 > 详细

Synchronized

时间:2019-10-04 19:02:50      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:16px   sync   font   实例   标记   类的方法   关键字   基于   分配   

 

 我们可以利用synchronized关键字来对程序进行加锁。它既可以用来声明一个synchronized代码块,也可以直接标记静态方法或者实例方法。
 
 
synchronized怎么实现线程的同步?
早期的synchronized属于重量级锁,依赖于mutex lock实现,线程之间的切换涉及到 用户态--》内核态的转换,由于状态的改变设计一个线程的所有变量状态的保存,以及空间的重新分配,系统开销十分巨大。
jdk1.6之后,引入了偏向锁,轻量级锁,在并发程度不是很高的情况下,也能保证良好的性能。
 
 
锁升级的步骤?
无锁--》偏向锁--》轻量级锁--》重量级锁
技术图片
偏向锁: 目的是减少同一线程获取锁的代价。大多数情况下,锁是不存在多线程竞争的,总是由同一个线程多次获得。
       偏向锁如何加:如果一个线程获得了锁,锁就进入了偏向模式。对象头MarkWorld的锁标志微为01,同时记录了该线程的线程id,当该线程再次请求锁的时候,无需再做任何同步操作,只需检查MarkWorld的锁标记位位现象锁以及线程id相同即可,色和功能区了中间有关锁申请的操作
轻量级锁:有偏向锁升级而来,偏向锁运行的一个线程进入同步块的情况下。当第二个线程加入锁竞争的时候,偏向锁就会升级为轻量级的锁。
  适用场景:线程交替执行同步块。
 
 

Synchronized和ReentrantLock区别?
1.Synchronized基于操作 MarkWord,ReentrantLock 调用Unsafe类的方法
2.ReentrantLock可以对获取锁的等待时间进行设置,避免死锁
3.ReentrantLock可以实现公平,非公平锁
4.ReentrantLock配合condition可以实现更加精确的线程控制
5.Synchronized无需进行锁的释放,ReentrantLock需要进行锁的释放

 
 
 
 

synchronized的线程同步在JVM层面,通过字节码中的monitorenter和monitorexit指令。

    public void test(Object lock){
        synchronized (lock){
            lock.toString();
        }
    }

 

技术图片

 

如果使用synchronized标记方法,你会看到字节码中方法的访问标记包括ACC_SYNCHRONIZED。
该标记表示在进入该方法时,Java 虚拟机同样需要进行monitorenter操作。

技术图片

 

 

 

锁优化的方案?

1.降低锁的时间(只需要在有线程安全要求的程序代码上加锁,而不是整个代码块加)

2.降低锁的细粒度(之前的ConcurrentHashMap通过减少锁的细粒度,提升性能)

3.读写分离(应用系统中,读操作次数远远大于写操作)

4.锁的粗化(通过把synchronized加载for循环外,避免每次for循环都涉及线程的切换)

5.锁消除(StringBuffer是一个局部变量,堆栈封闭,方法没有把StringBuffer返回,所以不可能会有多线程去访问它。

当我们在一些不会有线程安全的情况下使用这些类的方法时,达到某些条件时,编译器会将锁消除来提高性能。) 

Synchronized

标签:16px   sync   font   实例   标记   类的方法   关键字   基于   分配   

原文地址:https://www.cnblogs.com/Jemb/p/11617145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!