`
孙海友
  • 浏览: 24956 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

JDK设计模式应用之——单例模式(Singleton)

阅读更多

JDK设计模式应用——单例模式(Singleton)

    《JDK源码分析》的分支,讲解设计模式在jdk中使用。

    我们从三个方面讲述,一是:jdk源码中的设计模式;二是:讲解设计模式(UML图);三是:实现我们自己的设计模式代码。今天带来最简单的设计模式——单例模式(Singleton)

 

一、jdk源码中的设计模式

 

   我们先看java.lang包下的class Runtime

public class Runtime {

    private Runtime() {}//私有的构造方法

    //Runtime类的私有静态实例
    private static Runtime currentRuntime = new Runtime();

    //获得静态实例的唯一方法
    public static Runtime getRuntime() {
        return currentRuntime;
    }

}

    解释:

   (1)存在私有的构造函数,不能通过new来得到类的实例。

   (2)私有的静态实例,一个class只能对应唯一的对象。

   (3)只能通过:类.get方法获得这个唯一的对象实例。

 

     我们可以通过如下代码验证

Runtime r1 = Runtime.getRuntime();
Runtime r2 = Runtime.getRuntime();
//“==”为地址判断,为true表示:r1与r2指向同一对象。
System.out.println(r1 == r2);

   结果显然为:true

 

 

二、讲解设计模式(UML图)

 

                     

   上面是Singleton的UML图。

   单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。(来源——百度百科)

   单例模式的思想使用在很多方面,比如:一台计算机可以有若干打印机,但是一个时间只能有一个Printer Spooler,避免两个文件同时输入到打印机中。

   单例模式满足三个条件:

   (1)某个类只能有一个实例。

   (2)类必须自行创建这个类的实例(创建静态成员变量或者在类的静态方法中生成实例)。

   (3)类必须自行向整个系统提供这个实例。

 

 

 三、实现我们自己的设计模式

 

    我们实现单例模式分为两种:1、静态成员变量  2、静态方法(有人称为饿汉式和懒汉式

   1、静态成员变量

public class SingletonTest
{
        //在类里面实例化静态成员变量
	private static SingletonTest singletonTest = new SingletonTest();

	private SingletonTest()
	{
	}

	public static SingletonTest getInstance()
	{
		return singletonTest;
	}
}

 

 2、静态方法(最常用的方法)

public class SingletonTest
{
	private static SingletonTest singletonTest = null;

	private SingletonTest()
	{
	}

	public static SingletonTest getInstance()
	{
		//在类的静态方法中实例化单例
		if (null == singletonTest)
		{
			singletonTest = new SingletonTest();
		}

		return singletonTest;
	}
}

 

3、第二种方法构建单例模式是最常用的,但是在并发程序中会导致单例模式失效。

   如下面的代码所示:

public class SingletonTest
{
	private static SingletonTest singletonTest = null;

	private SingletonTest()
	{
	}

	public static SingletonTest getInstance()
	{
		if (null == singletonTest)
		{
			try
			{
				Thread.sleep((long) (Math.random() * 4000));
			} catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			singletonTest = new SingletonTest();
		}

		return singletonTest;
	}

	public static void main(String[] args)
	{
		// 打印出两个对象
		new ThreadTest().start();
		new ThreadTest().start();
	}
}

class ThreadTest extends Thread
{
	@Override
	public void run()
	{
		System.out.println(SingletonTest.getInstance());
	}
}

   输出的结果是:不是同一个对象,单例模式失效了。

com.shy.test.SingletonTest@55fe910c
com.shy.test.SingletonTest@3be4d6ef

   对于单例模式(Singleton)来说,如果在 getInstance()方法中生成 Singleton 实例则可能会产生同步问题,即可能会生成两个不同的对象。

 

  解释:

   当两个线程同时执行到getInstance()方法时,此时singletonTest为null,两个线程都会分别实例化出一个对象,因此出现了两个对象。

  解决方法:(使用synchronized解决同步问题)

 

public class SingletonTest
{
	private static SingletonTest singletonTest = null;

	private SingletonTest()
	{
	}

	public static SingletonTest getInstance()
	{
		synchronized (SingletonTest.class)
		{
			if (null == singletonTest)
			{

				singletonTest = new SingletonTest();

			}
		}

		return singletonTest;
	}

}

 

 

 

总结:Java中单例模式(Singleton Pattern)定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”

  • 大小: 8 KB
1
3
分享到:
评论
5 楼 孙海友 2014-03-26  
fisher123 写道
你这同步的解决办法也有问题的。比如2个线程同时进入到if(null==instance),此时都会去创建对象实例。虽然有同步关键字,但是在IF的时候,并没有进行排队。


其实最好的写法应该是这样的。
public class IndexNotify {
private IndexNotify() {}

private static class IndexNotifyHolder {
static IndexNotify instance = new IndexNotify();
}

public static IndexNotify getInstance() {
return IndexNotifyHolder.instance;
}
        }

有道理,我更新一篇博客,改进一下!
4 楼 孙海友 2014-03-26  
fisher123 写道
fisher123 写道
你这同步的解决办法也有问题的。比如2个线程同时进入到if(null==instance),此时都会去创建对象实例。虽然有同步关键字,但是在IF的时候,并没有进行排队。


其实最好的写法应该是这样的。
public class IndexNotify {
private IndexNotify() {}

private static class IndexNotifyHolder {
static IndexNotify instance = new IndexNotify();
}

public static IndexNotify getInstance() {
return IndexNotifyHolder.instance;
}
        }

因为静态内部类只有在使用的时候才会被Classloader 加载。而JVM 类加载的时候又是线程安全的。

IF判断要放到同步块中
3 楼 fisher123 2014-03-25  
fisher123 写道
你这同步的解决办法也有问题的。比如2个线程同时进入到if(null==instance),此时都会去创建对象实例。虽然有同步关键字,但是在IF的时候,并没有进行排队。


其实最好的写法应该是这样的。
public class IndexNotify {
private IndexNotify() {}

private static class IndexNotifyHolder {
static IndexNotify instance = new IndexNotify();
}

public static IndexNotify getInstance() {
return IndexNotifyHolder.instance;
}
        }

因为静态内部类只有在使用的时候才会被Classloader 加载。而JVM 类加载的时候又是线程安全的。
2 楼 fisher123 2014-03-25  
你这同步的解决办法也有问题的。比如2个线程同时进入到if(null==instance),此时都会去创建对象实例。虽然有同步关键字,但是在IF的时候,并没有进行排队。


其实最好的写法应该是这样的。
public class IndexNotify {
private IndexNotify() {}

private static class IndexNotifyHolder {
static IndexNotify instance = new IndexNotify();
}

public static IndexNotify getInstance() {
return IndexNotifyHolder.instance;
}
        }
1 楼 tomakemyself 2014-03-25  
                   

相关推荐

    JAVA设计模式在JDK中的应用

    ### JAVA设计模式在JDK中的应用 #### 一、引言 在软件开发过程中,设计模式作为一套被广泛接受的解决方案,能够帮助开发者解决常见的设计问题。Java作为一门流行的编程语言,其标准库(JDK)中巧妙地融入了多种设计...

    设计模式-单例模式

    **设计模式——单例模式** 单例模式是一种广泛应用于软件设计中的创建型设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制共享资源的访问,比如线程安全的数据库连接池...

    单例模式 Singleton Pattern

    单例模式是一种常见的设计模式,属于创建型模式之一。这种模式的核心在于确保某个类只有一个实例存在,并且提供一个全局访问点来获取该实例。单例模式在Java开发中尤其常见,因为它能够帮助开发者控制对象的创建过程...

    linux安装jdk(csdn)————程序.pdf

    正确安装JDK对于Java应用程序的运行至关重要。本文将指导您如何在Linux系统上安装JDK。 一、解压JDK 安装JDK的第一步是解压缩JDK安装包。通常,JDK安装包是一个tar.gz文件,可以使用tar命令来解压缩。例如,如果...

    Java设计模式源代码——自己看pdf写的

    下面将详细讨论Java设计模式的基本类型和应用场景。 1. **单例模式**: 单例模式确保一个类只有一个实例,并提供全局访问点。在Java中,通常使用双重检查锁定(DCL)或者静态内部类来实现线程安全的单例。单例模式...

    设计模式在JDK的中的应用,PPT资源

    设计模式在JDK中的应用课设--PPT资源 题目要求: 设计模式在JDK中的应用(结合JDK源码,分析JDK对设计模式的支持与应用)。课设内容包括: (a)用UML类图分析JDK所支持或应用的设计模式的结构,并与GOF的结构加以...

    centos配置JDK环境(csdn)————程序.pdf

    在Linux系统中,尤其是对于开发...在开发和维护Java应用程序时,正确配置JDK环境变量至关重要。它不仅方便了日常开发工作,还能确保系统的稳定性和兼容性。遵循上述步骤,你就能在CentOS上顺利地配置好JDK的环境变量。

    设计模式在JDK中的应用 (背景、UML结构、角色、职责)

    设计模式在JDK中的应用课设完整报告,Word文档 题目要求: 设计模式在JDK中的应用(结合JDK源码,分析JDK对设计模式的支持与应用)。课设内容包括: (a)用UML类图分析JDK所支持或应用的设计模式的结构,并与GOF的...

    [创建型模式] head first 设计模式之单件模式(Singleton)

    **单例模式(Singleton)**是软件设计模式中的一种创建型模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,例如管理共享资源、配置对象或者数据库连接等。单例...

    JDK中的设计模式

    Java Development Kit (JDK) 中包含了许多设计模式的应用实例,这些实例不仅展示了设计模式的强大功能,还为Java开发者提供了宝贵的参考。 #### 创建型模式 创建型模式关注的是对象的创建方式。通过这种方式,可以...

    JDK中的23个设计模式简介

    JDK 中的 23 个设计模式简介 在 Java 开发领域,设计模式是一个非常重要的概念,它能够帮助开发者写出更加灵活、可维护、可扩展的代码。JDK 中也提供了许多设计模式的实现,本文将对其中的 23 个经典设计模式进行...

    单例模式各种实现方式

    单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种方法,每种都有其特定的优缺点和适用场景。以下是几种常见的单例...

    小D深入浅出设计模式+框架源码剖析实战

    │ 3.5JDK源码里面的单例设计模式.mp4 │ 4.2电商支付应用案例-简单工厂模式实践指南.mp4 │ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》....

    设计模式实现——代理模式

    **设计模式实现——代理模式** 在软件工程中,设计模式是一种通用可重用的解决方案,它描述了在特定上下文中经常出现的问题以及该问题的解决方案。代理模式是设计模式的一种,它提供了一种对目标对象的间接访问方式...

    《Java设计模式》课后习题参考答案-刘伟(20180723).pdf

    JDK中许多类和方法都使用了设计模式,这些模式的应用帮助实现了代码的高内聚、低耦合,提高了代码的可维护性和扩展性。下面介绍几种常见的设计模式及其在JDK中的应用实例: a) 抽象工厂模式(AbstractFactory) ...

    1.设计模式-单例设计模式1

    单例设计模式是一种常用的设计模式,其主要目的是确保一个类只有一个实例,并提供全局访问点。在Java中,实现单例模式通常有多种方式,包括懒汉模式、饿汉模式、静态内部类以及枚举类型。 1. **懒汉模式**: 懒汉...

    jdk中设计模式

    1. **Singleton(单例模式)**:如`Runtime`和`NumberFormat`,确保一个类只有一个实例,提供全局访问点,避免多线程环境下产生多个实例的问题。 2. **Factory(静态工厂)**:例如`Integer.valueOf()`和`Class.for...

    设计模式实战、jdk源码|simple-demo.zip

    设计模式分为三大类:创建型模式(如单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式)、结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式、享元模式)和行为型模式(如...

    良葛格————JavaJDK5.0学习笔记PDF

    良葛格————JavaJDK5.0学良葛格————JavaJDK5.0学习笔记PDF.rar习笔记PDF.rar良葛格良葛格————JavaJDK5.0学习笔记PDF.rar————JavaJDK5.0学习笔记PDF.rar良葛格————JavaJDK5.0学习笔记PDF.rar良...

Global site tag (gtag.js) - Google Analytics