Java 多线程之单例设计模式
转载:https://segmentfault.com/a/1190000007504892
概念:
Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例、饿汉式单例。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
一、懒汉式单例 懒汉式单例类.在第一次调用的时候实例化自己
private Singleton() {}
private static Singleton s = null;
// 静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
return single;
}
}
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)
但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全,如果你第一次接触单例模式,对线程安全不是很了解,可以先跳过下面这三小条,去看饿汉式单例,等看完后面再回头考虑线程安全的问题:
1、在getInstance方法上加同步
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
2、双重检查锁定
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) { //静态方法中同步代码块的锁是字节码文件,即所在类的文件
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
3、静态内部类
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
这种比上面1、2都好一些,既实现了线程安全,又避免了同步带来的性能影响。
二、饿汉式单例
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton {
private Singleton() {}
private static final Singleton single = new Singleton();
//静态工厂方法
public static Singleton getInstance() {
return single;
}
}
饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
饿汉式和懒汉式区别
从名字上来说,饿汉和懒汉,
饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,
而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
另外从以下再区分以下这两种方式:
线程安全:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,
懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别。
Java 多线程之单例设计模式的更多相关文章
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- Java笔记(十一)……单例设计模式
设计模式 解决某一类问题最行之有效的方法 Java中有23中设计模式 单例设计模式 解决一个类在内存中只存在一个对象 思路 将构造函数私有化 在类中创建一个本类对象 提供一个方法可以获取到对象 两种方 ...
- Java学习笔记——单例设计模式Singleton
单例设计模式:singleton 解决的问题: 确保程序在运行过程中,某个类的实例instance只有一份. 特点: 1 构造函数私有化 2 自己内部声明自己 3 提供一个public方法,负责实例化 ...
- Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式
(一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00. 2.该类的很多方法都已经过时,不 ...
- Java面向对象_单例设计模式
单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 1.构造方法私有化 2.声明一个本类对象 3.给外部提供一个静态方法获取对象实例 两种实现方式:饿汉式和懒汉式 何种情况下使用呢?当 ...
- java中的单例设计模式
单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供 ...
- Java开发之单例设计模式
设计模式之单例模式: 一.单例模式实现特点:①单例类在整个应用程序中只能有一个实例(通过私有无参构造器实现):②单例类必须自己创建这个实例并且可供其他对象访问(通过静态公开的访问权限修饰的getIns ...
- Java并发-懒汉式单例设计模式加volatile的原因
懒汉式单例的double check.例一: class SingletonClass{ private static SingletonClass instance = null; private ...
- 02_javaSE面试题:单例设计模式
还记得很多年前,面试就让在白板上写个单例模式,当时技术渣渣,还写的是class A.面试官还说,你就不能写个Singleton. 面试题 编程题:写一个Singleton示例 解析 什么是Single ...
随机推荐
- http升https笔记
证书申请的: 1.lets encrypt 国际公益项目发展很快的,不过在国内暂时有些支持度还不够高,如微信安卓版就不认lets encrypt的证书.跳转进去一直处于空白页状态 2.沃通证书 国内 ...
- Android开发之---Activity启动模式
在Android开发中,启动一个新的activity我们可以使用startActivity或startActivityForResult,Android系统使用栈的方式来管理一个APP的页面显示与保存 ...
- LNMP平台搭建---MySQL安装篇
在前两篇中,安装了一个基本的Web服务器,但是只能提供静态网页查看,要做成动态网站,就必须要数据库或其他编程语言支持了,这里先介绍MySQL数据库的安装. MySQL是一个开源的数据库,在互联网行业应 ...
- 【转】B-树和B+树的应用:数据搜索和数据库索引
B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树: ⑴树中每个结点至多有m 棵子树: ⑵若根结点不是叶子 ...
- js生成带参的二维码
最近项目中有需求生成带参的二维码,考虑过用JAVA后台生成返回前端展示,后面了解到用jquery的qrcode.js插件可以很好现实 引入js: require.config({ baseUrl : ...
- HTTP错误500.19-定义了重复的节点
打开服务器的asp.net页面时出现这个错误: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. 解决办法: 打开II ...
- SQL 2012 Restore HeaderOnly
--USE [master] GO /****** Object: StoredProcedure [dbo].[zsp_RestoreHeaderOnly] Script Date: 2014/1/ ...
- java发送GET和post请求
package com.baqingshe.bjs.util; import java.io.BufferedReader; import java.io.IOException; import ja ...
- 逗号分割符--字段中含逗号等情况的解析方法Java实现
最近在处理文本字符串时,没一行数据都是按照逗号分割的,每个字段值一般情况是带有双引号的,但是有的字段值里面还包含逗号,甚至有的字段就没有双引号,这个分割起来就有点麻烦了 下面说一下我解决方法,如果谁有 ...
- Nagios配置文件详解
首先要看看目前Nagios的主配置路径下有哪些文件.[root@nagios etc]# ll总用量 152-rwxrwxr-x. 1 nagios nagios 1825 9月 24 14:40 ...