java设计模式之--单例模式

前言:最近看完《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

时间: 2024-11-04 11:33:47

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

(九)JAVA设计模式之单例模式

JAVA设计模式之单例模式 一.单例模式的介绍 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点.     全局对象和Singleton模式有本质的区别,因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本不支持全局变量.最重要的是传统的全局对象并不能阻止一个类被实例化多次. 二.单例模式的特点 单例类只能有一个实例 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例.

java 设计模式之单例模式

--------2015-11-20 14:45:10 java设计模式之单例模式(Singleton): ---应用场合:只需要一个对象就可以了,例如一个朝代一个皇帝. ---作用:保证某个应用程序中某个实例有且只有一个.共同使用一个,节省资源. ---类型:饿汉模式,懒汉模式. 一.饿汉模式(类加载的时候就会实例化,线程安全) 1 package com.sun.singleton; 2 3 //饿汉模式 4 public class Singleton { 5 6 //将构造函数私有化,不

java设计模式之单例模式(Singleton)

Java设计模式之单例模式 单例模式是什么? 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式如何来设计呢? 保证一个类只能有一个实例,那么我们不能无限制的new 来创建,因为我们知道,new一次就是一个新的对象,那么构造器只能私有化private -- 构造器私有化 构造器私有化了,问题又出现了,构造器私有化了,那么我们怎么来创建唯一的对象呢?-- 提供一个公有的方法/提供一个公有的静态属性 再分析一下,公有方法, 实例方法还是类方法呢?--公有的类方法(获取类实例) 依据以上

java设计模式之单例模式(Singleton pattern)

java设计模式之单例模式(Singleton pattern) 单例模式的定义: Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the i

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

Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleton instance; private Singleton (){}//私有化构造方法,防止类被实例化 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } retu

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

博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access to it. 一个类仅仅只有一个实例,并且提供全局的接入点.简洁点理解就是涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问它自己唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 饿汉式单例模式 public final class EagerSi

Java设计模式:单例模式

概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,但只能

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

原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话

Java 设计模式(3)单例模式

前言 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,

JAVA设计模式之单例模式(转)

本文继续介绍23种设计模式系列之单例模式. 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器