synchronized关键字的用法也不做太多笔记了,简单回顾一下;

synchronized三种使用方式:

修饰实例方法:

线程获取的是当前调用此方法的对象的对象头;即:锁是当前对象;

public synchronized void method(){  // ...
}

修饰静态方法:

线程获取的是此类的class对象,相当于synchronized(xxxx.class)

public synchronized static void test() {
  // ...
}

修饰代码块:

synchronized (this){
}
synchronized (MySynchronized.class){
}

synchronized与volatile

虽然volatile可以当做是轻量级的synchronized,但是它俩还是有一定区别的,比如volatile的禁止指令重排序;

在懒加载的双重校验单例模式下,这两个关键字都不可缺少:

由于饿汉单例的资源浪费,不用也加载,懒加载就很常用;

public class Singleton {
    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;
    }
}    

两个关键点:

1).为什么必须要用volatile?

new Singleton()其实是分为三步执行:

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

但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。

例如,线程 T1 执行了 1 和 3,此时 T2 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。

使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。

2)为什么双重校验?

如果没有第二次校验,一个线程在创建实例之前,另一个线已经通过了第一次校验,就会创建两个对象;

synchronized以前被称为重量级锁,效率很低;在JDK1.6之后,Java的锁优化机制,已经很丰富了,synchronized也被优化的很好了;

具体有关于锁机制,请看,个人觉得总结的还是很详细的:https://www.cnblogs.com/mussessein/p/11651148.html

【JUC】2.synchronized的更多相关文章

  1. 【JUC】4.Synchronized与ReentrantLock对比

    与synchronized相同,ReentrantLock也是一种互斥锁: synchronized与ReentrantLock的对比: 都是可重入锁 可以再次获取自己的内部锁,即:一个线程获取某对象 ...

  2. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  3. 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue

    概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...

  4. 【1】【JUC】JDK1.8源码分析之ReentrantLock

    概要: ReentrantLock类内部总共存在Sync.NonfairSync.FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQ ...

  5. 【JUC】阻塞队列&生产者和消费者

    阻塞队列 线程1往阻塞队列添加元素[生产者] 线程2从阻塞队列取出元素[消费者] 当队列空时,获取元素的操作会被阻塞 当队列满时,添加元素的操作会被阻塞 阻塞队列的优势:在多线程领域,发生阻塞时,线程 ...

  6. 【1】【JUC】Condition和生产者消费者模型

    本篇文章将介绍Condition的实现原理和基本使用方法,基本过程如下: 1.Condition提供了await()方法将当前线程阻塞,并提供signal()方法支持另外一个线程将已经阻塞的线程唤醒. ...

  7. 【JUC】synchronizated和lock的区别&新lock的优势

    原始构成 synchronized是关键字,属于JVM层面 javap -c 的结果显示 synchronized是可重入锁 11:是正常退出 17:是异常退出[保证不产生死锁和底层故障] Lock是 ...

  8. 【JUC】JUC锁框架综述

    一.前言 在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程.我们分为几个模块进行分析,首先是 ...

  9. 【JUC】如何理解线程池?第四种使用线程的方式

    线程池的概念 线程池的主要工作的控制运行的线程的数量,处理过程种将任务放在队列,线程创建后再启动折现任务,如果线程数量超过了最大的数量,则超过部分的线程排队等待,直到其他线程执行完毕后,从队列种取出任 ...

随机推荐

  1. 123457123456#0#-----com.tym.niuniuChengYu05--前拼后广--最牛成语tym

    com.tym.niuniuChengYu05--前拼后广--最牛成语tym

  2. Unity 3D网络游戏实战 pdf

    Unity 3D网络游戏实战(全) 目录: 掌握Unity3D基本元素 1.1 简单的游戏 1.1.1在场景中创建一个立方体 1.1.2编写可以使立方体运动的程序 1.1.3测试游戏1.1.4总结1. ...

  3. [转]C++ STL中的Binary search(二分查找)

    链接地址:https://www.cnblogs.com/wkfvawl/p/9475939.html

  4. antd一些问题

    1.去掉button光晕 用ant design中的Button的时候,每次点击都会在视图button上添加一个属性ant-click-animating-without-extra-node这个属性 ...

  5. LODOP注册语句相关简短问答

    注册和角色相关博文:LODOP.C-LODOP注册号的区别.Lodop客户端本地角色注册号常见误区.Lodop.c-lodop注册与角色简短问答.LODOP和C-LODOP注册与角色等简短问答[增强版 ...

  6. python3传文件到linux服务器然后解压

    #!/usr/bin/env python # -*- coding:utf-8 -*- import os import paramiko import time from scp import S ...

  7. 如何解决mac brew遇到无法下载的依赖?

    使用brew安装软件时,需要下载依赖包,但是如果依赖包特别大的时候,就很容易失败:brew本身不支持断点续传:但是可以使用wget -c的方式断点续传的下载依赖:下载完如何给brew安装使用呢?参考: ...

  8. MySQL 过滤复制+复制映射 配置方法

    场景 node1 和 node2 为两台不同业务的MySQL服务器.业务方有个需求,需要将node1上的 employees库的departments .dept_manager 这2张表同步到 no ...

  9. Quartz.Net—IJob特性

    IJob默认情况下是无状态的,和其他系统没有关系  特别是job里面的jobdata每次都是新的.可以无限扩展. PersistJobDataAfterExecution JobData持久化 Job ...

  10. MySQL 索引最佳实践

    原文请关注 这里 这是 文章 的翻译,在翻译过程中,会对其中涉及到的语句加上一些个人理解以及 SQL 语句的执行,并进行特别的标注. 1. 你做了一个很棒的选择,因为: 对于普通开发者和 DBA,理解 ...