Java多线程——volatile&synchronized

 

 

  首先来阐述一下并发编程三大特性,分别是:原子性可见性以及有序性

  • 原子性:指在一次或多次操作中,要么这些操作都进行,要么都不进行 。
  • 可见性:当一个线程对共享变量修改后,其他线程立马可以得到最新的值。
  • 有序性:指代码运行的现后顺序,java编译和运行期优化会使得代码执行顺序不同于编写顺序。

 

  1. 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)作用同①



 

posted @ 2020-10-06 11:17  emperorChen  阅读(136)  评论(0)    收藏  举报