首先我们要了解一下是什么是控制层面的区别,这里提到两点:
1.执行控制 目的是控制代码执行(顺序)及是否可以并发执行。
2.内存可见控制 线程执行结果在内存中对其它线程的可见性。根据Java内存模型的实现,线程在具体执行时,会先拷贝主存数据到线程本地(CPU缓存), 操作完成后再把结果从线程本地刷到主存
1.synchronized会阻止其他线程获取当前的锁。
2.并且synchronized会将数据直接刷到主存,保证数据的可见性,同时也使得这个锁线程的所有操作都happends-before于之后获得这个锁的线程的操作。
1.直接将数据刷到主存,保证内存可见性。
2.禁止指令重排("为了提高性能,编译器和处理器会对指令做重排序")
3.具有可见性、有序性,不具备原子性。
注“内存屏障指令保证了所有CPU操作结果都会直接刷到主存中。将刷出所有在Barrier之前写入 cache 的数据,因此,任何CPU上的线程都能读取到这些数据的最新版本。
1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。 5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
原文:https://www.cnblogs.com/tianxin945/p/12328938.html