前言:最近看完《java多线程编程核心技术》一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持。

单例模式,也就是一个类只有一个实例,任何对象要访问这个类只能通过这个实例对象来访问,我们把房子比喻一个java类,每个房子只有一把钥匙(好比每个类只有一个实例),这样唯有房子的主人才有这个钥匙才能访问房子,其他人访问不了。

我们来看一下怎么写一个单例模式的java代码,方法有很多种:

1.立即加载(也叫饿汉模式)

我们来看下具体的代码

package singleton;

public class Myclass {
//类加载初始化的时候就会生成一个实例
private static Myclass myclass=new Myclass();
//把构造函数使用private修饰符修饰
private Myclass() {
}
public static Myclass getInstance() {
return myclass;
} }

既然构造函数是私有的,那我们怎么调用这个类的对象呢?我们可以通过类名+方法的方式来获取这个对象,代码如下:

package singleton;

public class Test1 {

    public static void main(String[] args) {
//不能通过new来生成一个Myclass对象,编译报错
//Myclass myclass=new Mycalss();
Myclass myclass1=Myclass.getInstance();
Myclass myclass2=Myclass.getInstance();
//我们来打印一下上面两个对象的hashcode
System.out.println(myclass1.hashCode());
System.out.println(myclass2.hashCode());
} }

2.延迟加载(也叫懒汉模式)

下面我们来看看懒汉模式,也就是调用get方法的时候才实例化一个对象出来

package singleton;

public class Myclass_1 {
private static Myclass_1 myclass_1;
private Myclass_1() {
}
public static Myclass_1 getInstance() {
if (myclass_1!=null) { } else {
myclass_1=new Myclass_1();
}
return myclass_1;
} }

测试代码

package singleton;

public class Test1 {

    public static void main(String[] args) {
//不能通过new来生成一个Myclass对象,编译报错
//Myclass myclass=new Mycalss();
/*Myclass myclass1=Myclass.getInstance();
Myclass myclass2=Myclass.getInstance();*/
Myclass_1 myclass1=Myclass_1.getInstance();
Myclass_1 myclass2=Myclass_1.getInstance();
//我们来打印一下上面两个对象的hashcode
System.out.println(myclass1.hashCode());
System.out.println(myclass2.hashCode());
} }

运行结果和上面的图是一样的

其实这里有一个很大的问题。那就是懒汉模式在多线程模式下是完全错误的

我们来看看在多线程下是什么样子的

线程类代码如下:

package singleton;

public class Mythread extends  Thread{
public void run() {
System.out.println(Myclass_1.getInstance().hashCode());
}
}

测试代码:

package singleton;

public class RunTest {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Mythread().start();
}
}
}

运行结果

可以看出在多线程下生成了两个不同的实例对象。而我们想要的是单例啊

下面的做法是直接在用synchronized关键字修饰getInstance,但是这个这样会锁住整个方法,效率低下

package singleton;

public class Myclass_1 {
private static Myclass_1 myclass_1;
private Myclass_1() {
}
public static synchronized Myclass_1 getInstance() {
if (myclass_1!=null) { } else {
myclass_1=new Myclass_1();
}
return myclass_1;
} }

下面的方法是使用同步语句块来做,效率也同样低下,和上面的做法半斤八两

package singleton;

public class Myclass_1 {
private static Myclass_1 myclass_1;
private Myclass_1() {
}
public static Myclass_1 getInstance() {
synchronized (Myclass_1.class) {
if (myclass_1!=null) { } else { myclass_1=new Myclass_1();
}
} return myclass_1;
} }

我们来看看最高效的方法吧(何为高效?就是尽量把锁住的代码块缩小范围而又不发生错误),使用DCK双检查锁机制来解决

代码如下:

package singleton;

public class Myclass_1 {
private static Myclass_1 myclass_1;
private Myclass_1() {
}
public static Myclass_1 getInstance() {
if (myclass_1!=null) { } else {
synchronized (Myclass_1.class) {
            //再次判断
if (myclass_1==null) { myclass_1=new Myclass_1();
}
}
}
return myclass_1;
} }

欢迎访问我的个人网站

www.fanwencong.com

java设计模式之--单例模式的更多相关文章

  1. java 设计模式之单例模式

    -------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...

  2. 折腾Java设计模式之单例模式

    博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...

  3. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...

  4. Java 设计模式之单例模式(一)

    原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...

  5. java设计模式1——单例模式

    java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...

  6. java设计模式之单例模式你真的会了吗?(懒汉式篇)

    java设计模式之单例模式你真的会了吗?(懒汉式篇) 一.什么是单例模式? 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供 ...

  7. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  8. java设计模式- (1)单例模式

    参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. java设计模式之单例模式(七种方法)

    单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...

随机推荐

  1. JdbcTemplate+PageImpl实现多表分页查询

    一.基础实体 @MappedSuperclass public abstract class AbsIdEntity implements Serializable { private static ...

  2. Android调用微信登陆、分享、支付

    前言:用了微信sdk各种痛苦,感觉比qq sdk调用麻烦多了,回调过于麻烦,还必须要在指定包名下的actvity进行回调,所以我在这里写一篇博客,有这个需求的朋友可以借鉴一下,以后自己别的项目有用到也 ...

  3. 设计模式C#合集--抽象工厂模式

    抽象工厂,名字就告诉你是抽象的了.上代码. public interface BMW { public void Drive(); } public class BMW730 : BMW { publ ...

  4. ABP领域层

    1.实体Entites 1.1 概念 实体是DDD(领域驱动设计)的核心概念之一. 实体是具有唯一标识的ID且存储在数据库总.实体通常被映射成数据库中的一个表. 在ABP中,实体继承自Entity类. ...

  5. Android系统默认对话框添加图片

    开发工具Android Studio 今天公司UI要求软件对话框改成加图片的,以前没有做过,所以就学习了一下,废话不多说, 看效果: 创建XML文件dialog_lsit_item.xml <L ...

  6. HA 高可用软件系统保养指南

    又过了一年 618,六月是公司一年一度的大促月,一般提前一个月各系统就会减少需求和功能的开发,转而更多去关注系统可用性.稳定性和管控性等方面的非功能需求.大促前的准备工作一般叫作「备战」,可以把线上运 ...

  7. css实现文本框和下拉框结合的案例

    html 代码部分 <div id="list-name-input" class="list-name-input"> <select ty ...

  8. (一)Spark简介-Java&Python版Spark

    Spark简介 视频教程: 1.优酷 2.YouTube 简介: Spark是加州大学伯克利分校AMP实验室,开发的通用内存并行计算框架.Spark在2013年6月进入Apache成为孵化项目,8个月 ...

  9. 如何搭建git服务器

    一.前言 现在越来越多的公司用git进行版本控制,不过git是默认是开源的,如果私有的话是需要付费的,如果不想付费自己可以搭建一个git服务器用来版本控制. 二.服务器端操作 1.安装git sudo ...

  10. Configure a VLAN (on top of a bond) with NetworkManager (nmcli) in RHEL7

    not on top of a bond Environment Red Hat Enterprise Linux 7 NetworkManager Issue Need an 802.1q VLAN ...