Java 并发编程线程锁机制 ( 线程安全 | 锁机制 | 类锁 | 对象锁 | 轻量级锁 | 重量级锁 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 并发编程线程锁机制 ( 线程安全 | 锁机制 | 类锁 | 对象锁 | 轻量级锁 | 重量级锁 )相关的知识,希望对你有一定的参考价值。





一、线程安全



多个线程同时访问 同一个共享变量 时 , 只要能保证 数据一致性 , 那么该变量是线程安全的 ; 这里的数据是指主内存中的共享变量以及各个线程中的变量副本 , 保证这些变量一致 , 就是线程安全 ;

线程安全 就是保证 线程操作的 原子性 , 可见性 , 有序性 ;

volatile 关键字可以保证 可见性 有序性 ;

synchronized 关键字可以保证 原子性 ;





二、锁机制 ( 类锁 | 对象锁 )



synchronized 是 Java 提供的一种锁机制 ;

在普通方法上加锁 , 相当于对 this 进行加锁 ; 下面两个类的 fun 方法的线程锁是等效的 ;

public class Student {
    private synchronized void fun() {
    }
}
public class Student {
    private void fun() {
        synchronized(this){
        }
    }
}

加锁的代码块 , 在同一个时间 , 只能由 1 1 1 个线程访问 ;


对象锁 : synchronized() 代码块中 , 括号中的参数是 作用范围 ; synchronized(this) 表示作用范围只针对当前对象 , 如果 创建了多个对象 , 这几个对象中的锁都是 不同的锁 , 相互之间没有任何关系 ;

Student s1 = new Student();
Student s2 = new Student();

只有当多个线程 , 访问同一个对象时 , 锁才有意义 ;

如 :
线程 A 访问 s1 对象的 fun 方法 , 线程 B 访问 s2 对象的 fun 方法 , 两个方法之间 没有互斥效果 ;
线程 A 访问 s1 对象的 fun 方法 , 线程 B 也想访问 s1 对象的 fun 方法 , 此时必须 等待线程 A 访问完毕 , 释放锁之后 , 才能由线程 B 访问 s1 ;


类锁 : 如果加锁的对象是静态方法 , 那么相当于在 Student.class 类上进行加锁 ; Student.class 对象全局只有 1 1 1 个 , 调用所有对象的 fun 方法 , 都是互斥的 ;

public class Student {
    private synchronized static void fun() {
    }
}

等价于

public class Student {
    private static void fun() {
        synchronized(Student.class){
        }
    }
}




三、锁分类 ( 轻量级锁 | 重量级锁 )



如果线程 A 获得锁之后 , 执行线程内容 , 其它线程等待解锁时有两种情况 :

  • 轻量级锁 : 又称为 自旋锁 , 线程 盲等待 或 自旋等待 , 即 while 循环 , 没有进入阻塞状态 , 没有进入等待队列中排队 ; ( 轻量级 )
  • 重量级锁 : 线程进入 等待队列 , 排队等待线程 A 执行完毕 ; 在该队列的线程 , 需要 等待 OS 进行线程调度 , 一旦涉及到操作系统 , 量级就变重 , 效率变低 ; ( 重量级 )

轻量级锁弊端 : 轻量级锁 不一定 比重量级锁 更好 ; 轻量级锁 等待过程中 , 高速执行循环代码 , 如果循环的时间很短 , 时间效率上很高 ; 但是一旦执行时间很长 , 比如连续执行十几秒甚至几分钟 , 浪费了大量的 CPU 资源 ;


使用场景 :

  • 轻量级锁 : 轻量级锁只适合 线程少 , 等待时间短的 应用场景 , 如果线程很多 , 等待时间过长 , 会造成 CPU 大量浪费 ;
  • 重量级锁 : 重量级锁等待过程中 , 线程处于阻塞状态 , 效率可能低一些 , 但是不会造成资源浪费 , 如果 线程很多 , 或 等待时间很长 , 适合使用重量级锁 ;

以上是关于Java 并发编程线程锁机制 ( 线程安全 | 锁机制 | 类锁 | 对象锁 | 轻量级锁 | 重量级锁 )的主要内容,如果未能解决你的问题,请参考以下文章

java并发编程常见锁类型

Java 并发编程线程锁机制 ( 悲观锁 | 乐观锁 | CAS 三大问题 | ABA 问题 | 循环时间长问题 | 多个共享变量原子性问题 )

java并发编程:管程内存模型无锁并发线程池AQS原理与锁线程安全集合类并发设计模式

java并发编程:管程内存模型无锁并发线程池AQS原理与锁线程安全集合类并发设计模式

Java线程与并发编程实践----锁框架

Java并发编程:Java中的锁和线程同步机制