Java回顾一下Java中的synchronized

Posted

tags:

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

synchronized在JDK1.5之前是一个重量级锁,相当于JUC里面的lock锁,但是在1.6版本及之后对它做了很大的升级和优化,它不在那么的笨重了。

synchronized的作用主要有三个: 原子性:确保线程互斥的访问同步代码。 可见性:保证共享变量的修改能够及时可见 有序性:有效解决重排序问题,即一个unlock操作先行发生于后面对同一个锁lock操作。

synchronized的使用

synchronized的三种使用方式:

  • 修饰实例方法:作用于当前实例加锁。 代码里面是在方法前面加上synchronized,就是publich后加上synchronized,代码实例如下:
public synchronized method()
  // todo 实现方法

修饰静态方法:作用于当前类对象加锁 静态方法是属于类而不是对象的。同样的synchronized修饰的静态方法说的是这个类的所有对象

public synchronized static void method() 
   // todo

修饰代码块:指定加锁对象,对给定对象加锁。 一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。

synchronize的底层实现

在JVM中对象在内存的布局分为三块区域:对象头,实例数据和对齐填充。那synchronized的底层实现,锁就是存在对象头里的,那为什么是对象头呢?hotspot虚拟机的对象头主要包括两部分数据:Mark Word(标记字段),class pointer(类型指针)。其中class point是对象指向它的类元素的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。Mark Word用于存储对象自身运行时的数据,它是实现轻量级锁和偏向锁的关键。

synchronized在JVM里面实现都是基于进入和退出monitor对象来实现方法同步和代码块同步的,具体细节都可以通过对monitorEnter和monitorEixt实现的。 monitorEnter指令:插入在代码块的开始位置,当代码执行带该指令时,将会尝试获取对象monitor的所有权,即尝试获得该对象锁。 monitorExit指令:插入在方法结束和异常出,JVM保证每个monitorEnter都有对应的monitorExit

Synchronized锁升级的顺序

Synchronized在1.6之前是重量级锁,如果第一个线程使用了它,下一个线程想要使用就得等它释放了才能使用。如果发成阻塞了就得一直等待下去,所以效率低下。 1.6之后做了很大的优化,有了锁升级的过程。依次是:无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态。锁是单向执行只能升级,不能降级的。这个过程也是开销逐渐加大的过程。 一开始如果是一个线程的时候是无锁状态,下一次同一个线程进来还是无锁状态,如果有其他线程跟第一个线程进行竞争就会升级为CAS偏向锁,若锁竞争激烈就会升级会轻量级锁,最后升级为重量级锁。

以上是关于Java回顾一下Java中的synchronized的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Java中的同步静态方法和synchronized(class)代码块的类锁

回顾一下synchronized关键字,多线程编程的思路

java基础回顾线程详解以及synchronized关键字

Java同步锁Synchronized底层源码和原理剖析

4个点说清楚Java中synchronized和volatile的区别

java中的LinkedList,回顾一下