前言:最近看完《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. 【.net 深呼吸】细说CodeDom(1):结构大观

    CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...

  2. 页面嵌入dom与被嵌入iframe的攻防

    1.情景一:自己的页面被引入(嵌入)至别人的页面iframe中 if(window.self != window.top){ //url是自己页面的url window.top.location.hr ...

  3. 制作类似ThinkPHP框架中的PATHINFO模式功能

    一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...

  4. 移动端IOS点击事件失效解决方案

    解决方案 解决办法有 4 种可供选择: 1 将 click 事件直接绑定到目标元素(即 .target)上 2 将目标元素换成 <a> 或者 button 等可点击的元素 3 将 clic ...

  5. [APUE]UNIX进程的环境(上)

    一. 前言 本章将学习:当执行程序时,其main函数是如何被调用的,命令行参数是如何传送给执行程序的,典型的存储器布局是什么样式,如何分配另外的存储空间,进程如何使用环境变量,进程终止的不同方式等.另 ...

  6. 转:聊聊mavenCenter和JCenter

    Gradle支持从maven中央仓库和JCenter上获取构件,那这两者有什么区别呢? maven中央仓库(http://repo1.maven.org/maven2/)是由Sonatype公司提供的 ...

  7. HTML块级元素

    前面的话   在HTML5出现之前,人们一般把元素分为块级.内联和内联块元素.本文将详细介绍HTML块级元素 h   标题(Heading)元素有六个不同的级别,<h1>是最高级的,而&l ...

  8. SQL Server2016升级前几点自检

    SQL Server2016已经出来一段时间了,而且最新的SP1包也于2016年11月18日正式发布,各种新的特性推出让我们跃跃欲试.那么对于我们真实的业务环境,特别是生产环境要不要"跟风& ...

  9. 真假4K电视验证:一张图足矣

    国庆期间笔者逛了一下电视卖场,考虑到国内电视台以及宽带的情况,1080P至少还能用十年,所以只想要个2k电视就够了.然而事与愿违,卖场中八成的都是4k电视,清一色的4k电视让人眼花缭乱.难道4k面板技 ...

  10. Android之数据存储的五种方法

    1.Android数据存储的五种方法 (1)SharedPreferences数据存储 详情介绍:http://www.cnblogs.com/zhangmiao14/p/6201900.html 优 ...