synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性

synchronized、volatile区别、synchronized锁粒度

synchronized

synchronized是Java中的关键字,是一种同步锁。有以下几种用法:

用法

1、修饰方法:在范围操作符之后,返回类型声明之前使用。每次只能有一个线程进入该方法,
		此时线程获得的是成员锁。
2、修饰代码块:每次只能有一个线程进入该代码块,
		此时线程获得的是成员锁。
3、修饰对象:如果当前线程进入,那么其他线程在该类所有对象上的任何操作都不能进行,
		此时当前线程获得的是对象锁。
4、修饰类:如果当前线程进入,那么其他线程在该类中所有操作不能进行,包括静态变量和静态方法,
		此时当前线程获得的是对象锁。

volatile

volatile 关键字的作用是禁止指令的重排序,强制从公共堆栈中取得变量的值,而不是从线程私有的数据栈中取变量的值。

  • volatile与synchronized的区别如下:

1)volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。
2)volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。
3)volatile仅能实现变量修改的可见性,而synchronized则可以保证变量修改的可见性和原子性。《Java编程思想》上说,定义long或double时,如果使用volatile关键字(简单的赋值与返回操作),就会获得原子性。(常规状态下,这两个变量由于其长度,其操作不是原子的)
4)volatile不会造成线程阻塞,synchronized会造成线程阻塞。
5)使用volatile而不是synchronized的唯一安全情况是类中只有一个可变的域。

lock

  • synchronized是隐式锁,在需要同步的对象中加入此控制,而lock是显示锁,需要显示指定起始位置和终止位置。
  • 使用lock时在finally中必须释放锁,不然容易造成线程死锁;而使用synchronized时,获取锁的线程会在执行完同步代码后释放锁(或者JVM会在线程执行发生异常时释放锁)。
    使用lock时线程不会一直等待;而使用synchronized时,假设A线程获得锁后阻塞,其他线程会一直等待。
  • lock可重入、可中断、可公平也可不公平;而synchronized可重入但不可中断、非公平。

模拟死锁场景

https://blog.csdn.net/a158123/article/details/78616562

原文地址:https://www.cnblogs.com/inyu/p/13659064.html