1、为什么会用到synchronized
Java语言的一个高级特性就是支持多线程,线程在操作系统的实现上,可以看成是轻量级的进程,同一进程中的线程都将共享进程的内存空间,所以Java的多线程在共享JVM的内存空间。JVM的内存空间主要分为:程序计数器、虚拟机栈、本地方法栈、堆、方法区和运行时常量池。
在这些内存空间中,我们重点关注栈和堆,这里的栈包括了虚拟机栈和本地方法栈(实际上很多JVM的实现就是两者合二为一)。在JVM中,每个线程有自己的栈内存,其他线程无法访问该栈的内存数据,栈中的数据也仅仅限于基本类型和对象引用。在JVM中,所有的线程共享堆内存,而堆上则不保存基本类型和对象引用,只包含对象。除了重点关注的栈和堆,还有一部分数据存放在方法区,比如类的静态变量,方法区和栈类似,只能存放基本类型和对象引用,不同的是方法区是所有线程共享的。
如上所述,JVM的堆(对象信息)和方法区(静态变量)是所有线程共享的,那么多线程如果访问同一个对象或者静态变量时,就需要进行管控,否则可能出现无法预测的结果。为了协调多线程对数据的共享访问,JVM给每个对象和类都分配了一个锁,同一时刻,只有一个线程可以拥有这个对象或者类的锁。JVM中锁是通过监视器(Monitors)来实现的,监视器的主要功能就是监视一段代码,确保在同一时间只有一个线程在执行。每个监视器都和一个对象关联,当线程执行到监视器的监视代码第一条指令时,线程获取到该对象的锁定,直到代码执行完成,执行完成后,线程释放该对象的锁。
synchronized就是Java语言中一种内置的Monitor实现,我们在多线程的实现上就会用到synchronized来对类和对象进行行为的管控。