美文网首页线程
synchronized 关键字

synchronized 关键字

作者: happyJared | 来源:发表于2019-07-03 07:53 被阅读0次

    synchronized 关键字解决的是多个线程间访问同一资源的同步性问题。

    早期版本中,synchronized 属于重量级锁,效率低下,这是由于监视器锁(monitor)是依赖于底层操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上。如果要挂起或者唤醒线程,都需要操作系统帮忙完成,而操作系统进行线程间的切换时,需要从用户态转换到内核态,这个状态的转换需要相对长的时间,时间成本较高,这也就是早期 synchronized 效率低下的主要原因。庆幸的是,Java1.6 以后官方对 synchronized 做了较大的优化,因此现在的 synchronized 锁效率也是比较高的(推荐先使用)。

    synchronized 关键字最主要的三种使用方式:

    1. 修饰实例方法: 给当前对象实例加锁,进入同步代码前要获得当前对象实例的锁;
    2. 修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,(static 修饰表明是类成员,是该类的一个静态资源,所以不管 new 了多少个对象,应有中也只有一份)。如果一个线程 A 调用一个实例对象的非静态 synchronized 方法,而线程 B 调用这个实例对象所属的类的静态 synchronized 方法,这是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象的锁;
    3. 修饰代码块: 指定加锁对象,对给定对象加锁,进入同步代码块前要获得给定对象的锁。

    synchronized 关键字加到 static 静态方法和 synchronized(class) 代码块上都是对当前 Class 类上锁;
    synchronized 关键字加到实例方法上是给对象实例上锁;
    尽量不要使用 synchronized(String s),因为 JVM 中,字符串常量池具有缓存功能。

    • 代码示例:双重校验锁(DCL)实现的对象单例(线程安全)
    public class Singleton {
    
        // DCL 方式的单例需确保使用 volatile 
        private volatile static Singleton uniqueInstance;
    
        // 私有化构造器
        private Singleton() {
        }
    
        public static Singleton getUniqueInstance() {
           // 先判断对象是否已经实例过,没有实例化过才进入加锁代码
            if (uniqueInstance == null) {
                //类对象加锁
                synchronized (Singleton.class) {
                    if (uniqueInstance == null) {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    
    }
    

    使用 volatile 关键字可以禁止 JVM 的指令重排,保证多线程环境下代码也能正常执行.。

    以上 uniqueInstance = new Singleton(); 这段代码其实是分为三步执行:

    1. 为 uniqueInstance 分配内存空间
    2. 初始化 uniqueInstance
    3. 将 uniqueInstance 指向分配的内存地址

    由于 JVM 具有指令重排的特性,所以上述执行顺序有可能变成 1->3->2,指令重排在单线程环境下不会有问题,但多线程下会导致线程可能得到还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。

    相关文章

      网友评论

        本文标题:synchronized 关键字

        本文链接:https://www.haomeiwen.com/subject/cvlthctx.html