线程之Synchronized基本内容


1.Synchronized关键字

1. 定义

Java中的1个关键字

2. 作用

   保证同一时刻最多只有1个线程执行。被Synchronized修饰的方法 / 代码,其他线程 必须等待当前线程执行完该方法 / 代码块后才能执行该方法 / 代码块。

3. 应用场景

保证线程安全,解决多线程中的并发同步问题(实现的是阻塞型并发),具体场景如下:

  1. 修饰 实例方法 / 代码块时,(同步)保护的是同一个对象方法的调用 & 当前实例对象
  2. 修饰 静态方法 / 代码块时,(同步)保护的是 静态方法的调用 & class 类对象

4. 原理

  1. 依赖 JVM 实现同步
  2. 底层通过一个 监视器对象(monitor)完成, wait()notify() 等方法也依赖于 monitor 对象。
  3. 监视器锁(monitor)本质 依赖于 底层操作系统的互斥锁(Mutex Lock)实现

5. 具体使用

Synchronized 用于 修饰 代码块、类的实例方法 & 静态方法

5.1 使用规则

   

5.2 锁的类型 & 等级

  • 由于Synchronized 会修饰 代码块、类的实例方法 & 静态方法,故分为不同锁的类型
  • 具体如下
  示意图
  • 之间的区别
  示意图

5.3 使用方式

代码如下
  synchronized(syncObject) { 
    // 访问或修改被锁保护的共享状态 
    // 上述方法 必须 获得对象 syncObject(类实例或类)的锁
}

6. 特点

  示意图

注:原子性、可见性、有序性的定义

   

7. 其他控制并发 / 线程同步方式

7.1 Lock、ReentrantLock

  • 简介
 
  • 区别
   

7.2 CAS

7.2.1 定义

Compare And Swap,即 比较 并 交换,是一种解决并发操作的乐观锁。

synchronized锁住的代码块:同一时刻只能由一个线程访问,属于悲观锁

7.2.2 原理
// 1. CAS在Java中的体现为Unsafe类
// 2. Unsafe类会通过C++直接获取到属性的内存地址
// 3. 接下来CAS由C++的Atomic::cmpxchg系列方法实现
7.2.5 典型应用:AtomicInteger

对 i++ 与 i--,通过compareAndSet & 一个死循环实现

compareAndSet函数内部 = 通过jni操作CAS指令。直到CAS操作成功跳出循环

   private volatile int value; 
    /** 
     * Gets the current value. 
     * 
     * @return the current value 
     */ 
    public final int get() { 
        return value; 
    } 
    /** 
     * Atomically increments by one the current value. 
     * 
     * @return the previous value 
     */ 
    public final int getAndIncrement() { 
        for (;;) { 
            int current = get(); 
            int next = current + 1; 
            if (compareAndSet(current, next)) 
                return current; 
        } 
    } 
 
    /** 
     * Atomically decrements by one the current value. 
     * 
     * @return the previous value 
     */ 
    public final int getAndDecrement() { 
        for (;;) { 
            int current = get(); 
            int next = current - 1; 
            if (compareAndSet(current, next)) 
                return current; 
        } 
    }