Java多线程——volatile&synchronized
首先来阐述一下并发编程三大特性,分别是:原子性,可见性以及有序性。
- 原子性:指在一次或多次操作中,要么这些操作都进行,要么都不进行 。
- 可见性:当一个线程对共享变量修改后,其他线程立马可以得到最新的值。
- 有序性:指代码运行的现后顺序,java编译和运行期优化会使得代码执行顺序不同于编写顺序。
- volatile
每个线程在操作数据时,会先从缓存获取数据,如果没有获取到再去主存中获取并添加到缓存中。高并发时,多线程修改共享资源,由于缓存机制,会使得主存中共享资源出现错误数据。
使用volatile修饰的变量,线程在读取该共享资源的数据时,也会使用缓存机制,但是在修改该资源时,会将该线程缓存中的资源一并修改,并刷新到主存中 。然后使得其他线程缓存中的数据失效。
简而言之就是:volatile让变量每次在使用的时候,都从主存中取。而不是从各个线程的“工作内存”。使用volatile修饰的变量,线程在读取该共享资源的数据时,也会使用缓存机制,但是在修改该资源时,会将该线程缓存中的资源一并修改,并刷新到主存中 。然后使得其他线程缓存中的数据失效。
一般来说,当我们要将一个变量作为一个线程内的“开关”来使用时,volatile就该上场了!
2.synchronized
特点:
- synchronized是Java中常见的同步锁,它不同于Lock锁类(需自己显示上锁解锁),不能显示的释放锁,是一种自动释放的加锁机制。
- 是一种非公平锁(每个线程抢占锁的顺序不定,谁运气好,谁就获取到锁,和调用lock方法的先后顺序无关,可能会饿死)
- 可以作用于方法前,方法内代码块,作用于类。但其所加锁对象为不同实例对象时,互斥失效。
用法:
1. 对象锁:针对对象
A.同步代码块形式:
①synchronized(this):同一个对象的多个线程,只能一个线程去执行同步区域.多个对象则互不影响.
②synchronized(Object lock):自定义锁,若存在lock1,lock2.可理解为不同的锁,互不干扰。
B.普通方法锁形式:
synchronized修饰普通方法,同A①(同一个对象的多个线程,只能一个线程去执行同步区域.多个对象则互不影响)
2.类锁:针对包括一个类下不同对象
①synchronized修饰静态方法(run重写方法不能修饰,故用②)
②synchronized(类名.class)作用同①

浙公网安备 33010602011771号