Java单例实现及分析
双重检验锁实现方式
public class Singleton {
//定义一个私有的空构造方法,防止直接用new实例化
private Singleton() {}
private static volatile Singleton singleton = null;
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
双重校验锁,从代码的中可以看出,在同步代码块外多了一层instance为空的判断,由于单例对象只需要创建一次,如果后面再次调用getInstance()只需要直接返回单例对象即可,因此,在大部分情况下,调用getInstance()都不会执行到同步代码块,从而提高的程序性能。但是还需要考虑一种情况,假如两个线程A、B,线程A执行了if(instance == null)语句,它会任务单例对象没有创建,此时线程切到B也执行了同样的语句,B也认为单例对象没有创建,然后两个线程一次执行同步代码块,并分别创建了一个单例对象,所以为了解决这个问题,还需要在同步代码块中增加if(instance == null)的语句判断,避免重复创建的问题。
可以发现instance变量使用了volatile修饰,这样做的目的在于禁止指令重排序优化,所谓指令重排序优化是指在不改变原语义的前提下,通过调整指令的执行顺序让程序运行的更快,JVM中并没有规定编译器优化的相关内容,也就是说JVM可以自由的镜像指令重排序优化,这样会导致Singleton和将对象赋值给instance字段的顺序是不确定的。在摸个线程创建单例对象时,在构造方法被调用之前,就为该对象分配了内存空间将对象的字段设置为默认值。此时就可以将分配的内存地址赋值给instance字段了,然而该对象可能还没有初始化,若紧接着另一个线程来调用getInsatance,取到的就是状态不正确的对象,程序就会出错。volatile的一个语义是禁止指令重排序优化,也就是保证了instance遍历被赋值的时候对象已经是初始化过的,从而避免上面说的问题。
静态内部类实现方式
public class Singleton{
private static class SingletonHolder{
public static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton newInstance(){
return SingletonHolder.instance;
}
}
这种方式同样利用了类加载机制来保证只创建一个instance实例。它与饿汉模式一样,也是利用了类加载机制,因此不存在多线程并发的问题。不一样的是,它是在内部类里面去创建对象实例。这样的话,只要应用中不使用内部类,JVM就不会去加载这个单例类,也就不会创建单例对象,从而实现懒汉式的延迟加载。也就是说这种方式可以同时保证延迟加载和线程安全。
Java单例实现及分析的更多相关文章
- java单例的几种实现方法
java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...
- java单例类/
java单例类 一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...
- java单例-积木系列
一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...
- Java单例类的简单实现
对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...
- 【Java学习笔记之三十】详解Java单例(Singleton)模式
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 转:java单例设计模式
本文转自:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton ...
- 熟悉的味道——从Java单例写到C++单例
设计模式中,单例模式是常见的一种.单例模式需要满足以下两个条件: 保证一个类只能创建一个示例: 提供对该实例的全局访问点. 关于单例最经典的问题就是DCL(Double-Checked Lock),今 ...
- java单例五种实现模式梳理
java单例五种实现模式 饿汉式(线程安全,调用效率高,但是不能延时加载) 一上来就把单例对象创建出来了,要用的时候直接返回即可,这种可以说是单例模式中最简单的一种实现方式.但是问题也比较明显.单例在 ...
- JAVA单例实现方式(常用)
JAVA单例实现方式(常用) public class Singleton { // Q1:为什么要使用volatile关键字? private volatile static Singleton u ...
随机推荐
- spring boot + vue + element-ui全栈开发入门——项目部署
前言 常用的部署方式有两种: 1.是把生成好的静态页面放到spring boot的static目录下,与打包后的spring boot项目一起发布,当spring boot运行起来后,自然而然就能访 ...
- [批处理]使用Log.io监控日志变化
背景 多台服务器安装了不同的开发服务,增加日志监控以随时处理情况 方案 log.io 环境 NodeJs 安装 1.log.io直接无法安装上,使用log.io-ts安装上 npm install - ...
- [NOIP2017赛前复习第二期]复赛考试技巧与模版-普及组
考试技巧 1.拿到考卷首先通看题目,按自己感觉的难度排序(普及一般是1-2-3-4了~还是相信出题人不会坑我们的2333) 2.一般来说,普及组前两道题比较简单(大水题啊233~),但是通常坑很多,例 ...
- 2018-2019-2 网络对抗技术 20165305 Exp4 恶意代码分析
Exp4 恶意代码分析 1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysi ...
- java问题排查之Load CPU很高
1首先 找到对应的java进程id ps -aux | grep java 这个命令可以找到 2.接下来就是查找比较耗CPU的线程id top -H -p pid 这里可以观察出来耗时最多的几个进程中 ...
- leetcode 最后一个单词的长度 python
class Solution: def lengthOfLastWord(self, s): """ :type s: str :rtype: int "&qu ...
- MyPython
目录 Python,那些不可不知的事儿 Python简介 Python环境搭建 从Hello World开始 Python中的数据类型 函数 模块 面向对象 More Python,那些不可不知的事儿 ...
- sql的优化
适当的索引 尽量不要有空判断的语句 尽量不要使用不等于条件 尽量不要使用or条件 尽量不要使用左右模糊查询 尽量使用exists代替in 尽量避免一次性返回大数据量
- 一个基于nuxt的基础架子,支持aixos,sass,es6,elementUI
nuxt官网:Nuxt.js docs github: 项目地址 项目版本说明 package 版本号 "babel-cli" "^6.26.0" " ...
- 立即执行函数(自执行函数) IIFE
// 最常用的两种写法 (function(){ /* code */ }()); // 老道推荐写法 (function(){ /* code */ })(); // 当然这种也可以 // 括号和J ...