锁是JAVA多线程关键,也是面试中必问的, 在此好好总结一下。
(先要从进程和线程说起,此处先欠下,回头专门说一下操作系统是怎么管理进程和线程的)
说到多线程就要说说JAVA的内存模型:图片来自于网络。
Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样底层细节。此处的变量与Java编程时所说的变量不一样,指包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,后者是线程私有的,不会被共享。
Java内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程使用到的变量到主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成,线程、主内存和工作内存的交互关系如上图所示。
这就有一个内存可见性的概念了。
如果变量在a线程中改变了,b线程要立马感知到,就要通过volatile关键字了。 其作用就是 b线程要用到此变量的时候,将本地副本抛弃掉,然后重新从主存去读取。
volatile 解决了线程共享变量的可见性,synchronized 也可以做到。
volatile 修饰变量 但是他解决不了原子性, 比如,volatile int count ; 方法中对其 count++ , 在多个线程对其操作,最终预期值会是错误的。解决方法可以加synchronized ,CAS。