Java.synchronized

  • Post author:
  • Post category:java


synchronized

1.synchronized是我们解决线程不安全问题的一种手段,通过加锁的方式,实现了原子性,内存可见性,对于指令重排序,有一定的约束,但是不是完全禁止。

2.synchronized的使用

synchronized是加锁,放在不同的地方,锁的对象也不一样。

(1)修饰代码块      synchronized修饰代码块的时候,需要显示的写出来锁对象是谁(锁对象可以是任意对象)。

(2)修饰普通方法      修饰普通方法,锁对象是该实例,比如同一个实例,同时执行两个被synchronized修饰的方法时,只能有一个方法执行。

(3)修饰静态方法      修饰静态方法时,锁对象是类对象,静态方法,不属于任一个实例方法

3.synchronized的特性。

(1)互斥     某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象synchronized就会阻塞等待。进入synchronized修饰的代码块就相当于加锁,退出就相当于解锁。

(2)刷新内存      即synchronized会在解锁前,一定保证把数据更新到了主内存里面。

(3)可重入         简单来说就是不会自己把自己锁死,在对象头里存有一部分内容,锁的持有者和计数器,如果一实例在执行被加锁的普通方法时,发现锁的持有者是他自己,那么就不再上锁,而是把计数器加1,这样就不会说因调用的方法里再调用加锁方法而导致的锁死问题。

4.synchronized是一个什么锁?

(这里的小结,只考虑了jdk8)

synchronized是一个乐观锁,也是一个悲观锁(主要看锁的竞争程度)。

synchronized不是读写锁,是普通的互斥锁。

synchronized是轻量级锁,也是重量级锁(随着锁的竞争程度的增加,会逐渐升级)。

synchronized开始是自旋锁,后面会逐渐升级。

synchronized是一个非公平锁,是一个可重入锁。

5.synchronized的锁机制/synchronized的锁升级,锁膨胀,锁消除,锁粗化

(1)锁升级/锁膨胀      无锁——>偏向锁——>自旋锁——>重量级锁,随着竞争程度的增加,synchronized的锁机制逐渐升级。(偏向锁并不是真正的锁,代表对某个线程有一定的偏向。大部分情况下,锁不仅不存在竞争,而且锁还经常由同一个对象获得。偏向锁就是一个标志,在对象头存储当前锁偏向的线程,当一个线程访问时,会先判断这个标志是否等于当前线程,如果等于当前线程,那就直接获得锁,如果为空,就把当前锁的对象头,设置成自己,如果不等于自己,锁就会升级)。

(2)锁消除      就是如果我们在一些不必要加锁的地方加了锁,那编译器或JVM会帮我们优化,将锁给消除掉。

(3)锁粗化       (粗细,指的是代码粒度的粗细,即加锁的代码的多或少)如果我们对一段代码频繁加锁,那么synchronized就会帮我们进行锁的粗化。

6.synchronized的原理

(1)synchronized的特性     原子性,内存可见性,有序性(指令重排序),非公平锁,可重入锁,不可中断(这里的不可中断不是指线程不能中断,而是指当拿不到锁的时候,这个阻塞的过程不可以中断)。

(2)synchronized的使用       修饰代码块,修饰普通方法,修饰静态方法。

(3)synchronized的锁机制        锁升级/锁膨胀,锁消除,锁粗化。

(4)synchronized的实现        主要跟monitor有关,监视器,每个对象都有一个monitor。



版权声明:本文为m0_58407085原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。