Synchronized

Posted jemb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Synchronized相关的知识,希望对你有一定的参考价值。

 

 我们可以利用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的主要内容,如果未能解决你的问题,请参考以下文章

锁之synchronized

synchronized

Synchronized

synchronized

关键字: synchronized详解

JAVA锁