搬以前写的博客【2014-12-30 16:04】

在web应用中服务器面临的是大量的访问请求,免不了多线程程序,但是有时候,我们希望在多线程应用中的某一个类只能新建一个对象的时候,就会遇到问题。

首先考虑单线程,如果要求只能新建一个对象,那么构造函数我们要设为private。简单的想法:
class singleton{
  private singleton(){
    //.....
  }
  private static singleton instance;
  public static singleton getinstance(){
    if(instance==null) //
    instance = new singleton(); //
    return instance
  }
}
这对于单线程是合理的,第一次调用singleton类时,会新建出singleton对象,但之后访问时,返回的是第一次新建的instance。
但多线程访问时,有可能同时进入//1处的条件判断,多次执行2代码,从而新建多个singleton对象。我们考虑使用同步关键字sycronized
class singleton{
  private singleton(){
    //.....
  }
  private static singleton instance;
  public static singleton synchronized getinstance(){
    if(instance==null) //
      instance = new singleton(); //
    return instance
  }
}
此时可以保证不出错,是单例模式的一种方案,但是问题是每次执行都要用到同步,开销较大。
另外一种想法是,双重检查锁,代码如下:
class singleton{
  private singleton(){
    //.....
  }
  private static singleton instance;
  public static singleton getinstance(){
    if(instance==null) { //
      sycronized(singleton.class){
        if(instance==null)
          instance = new singleton(); //
      }
    }
    return instance;
  }
}
此写法保证了,当多个进程进入第一个判断锁时,会被同步机制隔离,只有一个程序进入新建对象,再其他线程进入时,instance已经不为null,因此不会新建多个对象。这种方法就叫做双重检查锁,但是也有一个问题,就是java是实行无序写入的机制,在某个线程执行//2代码的过程中,instance被赋予了地址,但是singleton对象还没构造完成时,如果有线程访问了代码//1此时判断instance不为空,但是方法返回的是一个不完整对象的引用。此时可能会产生错误!
另外一种实现单例模式的写法就是
class singleton{
  private singleton(){
    //.....
  }
  private static singleton instance = new singleton();
  public static singleton getinstance(){
    return instance;
  }
}
这样就不会有之前的问题了。

【Java学习笔记】线程安全的单例模式及双重检查锁—个人理解的更多相关文章

  1. Java学习笔记 线程池使用及详解

    有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...

  2. Java 学习笔记 线程控制

    题目一 本质上来说,线程是不可控制的,线程的执行是由CPU资源分配决定的,我们无法干预系统CPU的资源分配,但我们可以增加条件来让线程按照我们的预想顺序来执行. 比如.如果当前的执行的线程不满足我们所 ...

  3. java学习笔记 - 线程池(一)

    线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销 优点:(面试题)可重复使用已有线程,避免对象创建.消亡和过度切换的性能开 ...

  4. java学习笔记 线程的实现与同步

    2019.4.2 线程实现的两种方式 继承线程,复写其中的run方法 实现runnable接口,复写run方法 使用: MyThread target = new MyThread(); new Th ...

  5. Java学习笔记--线程day01

    线程的概念:一个线程是进程的顺序执行流: 同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈.线程在切换时负荷小,因此,线程也被称为轻负荷进程.一个进程中可以有多个线程. ...

  6. Java学习笔记——线程

    线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...

  7. 双重检查锁实现单例(java)

    单例类在Java开发者中非常常用,但是它给初级开发者们造成了很多挑战.他们所面对的其中一个关键挑战是,怎样确保单例类的行为是单例?也就是说,无论任何原因,如何防止单例类有多个实例.在整个应用生命周期中 ...

  8. Java设计模式学习笔记,一:单例模式

    开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的 ...

  9. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

随机推荐

  1. [CSP-S模拟测试]:打扫卫生(暴力)

    题目描述 有$N$头奶牛,每头那牛都有一个标号$P_i1\leqslant Pi\leqslant M\leqslant N\leqslant 40,000$.现在$Farmer\  John$要把这 ...

  2. 大数据笔记(十七)——Pig的安装及环境配置、数据模型

    一.Pig简介和Pig的安装配置 1.最早是由Yahoo开发,后来给了Apache 2.支持语言:PigLatin 类似SQL 3.翻译器 PigLatin ---> MapReduce(Spa ...

  3. 含有对象的List集合实现字母数字混合排序

    List<PageData> varList = [{BOMCode=10A, mantotal=4}, {BOMCode=10B, mantotal=1}, {BOMCode=11A, ...

  4. C++ Primer 第四版阅读笔记

    阅读笔记 初始化 变量定义指定了变量的类型和标识符,也可以为对象提供初始值.定义时指定了初始值的对象被称为是 已初始化的.C++ 支持两种初始化变量的形式:复制初始化和 直接初始化.复制初始化语法用等 ...

  5. java1.8 10大新特性

    http://blog.csdn.net/u013598111/article/details/49720867 一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 d ...

  6. 年薪100万的人都是怎么玩Excel的?

    年薪100万的人都是怎么玩Excel的? 2017-12-21 13:42美国 作者:珍妮Jenny 来源:一周进步(ID:weekweekup) 本文已获原作者转载授权,如需转载请联系原公号 本文重 ...

  7. Oracle 10046 event

    http://czmmiao.iteye.com/blog/1497509 10046事件概述Oracle的10046事件,可以跟踪应用程序所执行的SQL语句,并且得到其解析次数.执行次数,CPU使用 ...

  8. python 多进程读写文件

    import time from multiprocessing import Process, JoinableQueue, cpu_count import csv ####处理一条数据的方法 d ...

  9. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第1节 Scanner类_5-练习二_键盘输入三个数字

    思路分析: 获取前两个数字中的看最大值,有多重写法,这里先演示第一种.三元运算符的方式  

  10. Bootstrap 学习笔记 项目实战 首页内容介绍 上

    效果图: HTML代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset ...