博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA单例模式详解
阅读量:5337 次
发布时间:2019-06-15

本文共 2582 字,大约阅读时间需要 8 分钟。

什么是单例模式

但是模式是在软件编程中常见的一种设计模式,并且是代码量很少的一种,这中设计模式并不是只限制于一种语言,这是在无数前辈哪里总结出来的一种软件设计思想,顾名思义单例模式在系统中只有一个实例化的对象,正如他的名字一样只有一个,单例模式最初出现在《设计模式》:保证一个类只有一个实例,并且提供一个访问他的全局访问点。

单例模式分为哪几种

1.饿汉式

2.懒汉式

3.最后我还要说下在多线程的模式下如何保证只能实例一个对象

饿汉式写法

饿汉式写法我想应该理解成像一个饥饿的汉子一样,不管在实际的情况需不需要创建这个类的对象,总之在第一次使用该类的时候就创建一个对象引用

如何写?我这里总结的3个步骤:

  1. 私有化构造方法
  2. 提供一个公共的方法,这个方法可以返回该类的实例对象
  3. 创建一个私有化的静态的类的对象 

    问:为什么要设置私有化的静态类对象?

    答:如果这里的对象时公有的那么我们可以通过在外界类名.对象名的修改这个对象,虽然说我们的构造方法是私有的我们不能new一个对象,但是我们可以将此设置为空,像下图似的如果是公有的就可以在外界修改了,这样很危险,所以这里要设置成私有的。

接下来我们看下代码如何编写和检测是否是整个程序只有一个对象

class A{	//创建一个私有静态的类对象	private static A a = new A();	//私有化构造	private A() {		System.out.println("创建了一个A的实例对象");	}	//提供一个共有的可以返回类对象的方法	public static A getSingleton() {		return a;	}}

在外界调用getSingleton方法来获取创建的对象

A.getSingleton();

接下来测试下是否只是创建了一个对象,我们这里通过For循环连续调用getSingleton方法,我在A类的构造方法里输出了一句话如果是创建了多个对象,肯定会多次输出这句话

public static void main(String[] args) {	for(int i = 0 ;i <500;i++) {		A.getSingleton();	}}

测试是否只有一个对象被实例化,结果输出如下,以此证明这样我们在整个程序中只是创建了一个对象

懒汉式写法

懒汉式写法可能是说这个程序比较懒吧,只有需要的时候他才实例化一个对象,这个部分代码是和饿汉式差不多的,只是在实例化对象的时候有所区别,懒汉式写法的步骤如下:

  1. 私有化构造方法
  2. 提供一个公共的方法,这个方法可以返回该类的实例对象
  3. 创建一个私有化的静态的类的对象   这里创建类的对象的时候不要直接new出来
  4. 在我们的返回对象的公共方法中写一个判空的处理

 来看下代码如何实现的

class A{	//创建一个私有静态的类对象	private static A a = null;	//私有化构造	private A() {		System.out.println("创建了一个A的实例对象");	}	//提供一个共有的可以返回类对象的方法	public static A getSingleton() {		if(a == null) {			a = new A();		}		return a;	}}

懒汉式的调用方法和饿汉式的一样

A.getSingleton();

这里我们也是通过for循环来测试下是否只有一个对象被实例化

public static void main(String[] args) {	for(int i = 0 ;i <500;i++) {		A.getSingleton();	}}

打印结果

在多线程中懒汉式写法出现的问题

public static void main(String[] args) {	for(int i = 0 ;i <500;i++) {		Thread thread = new Thread(()->{			A.getSingleton();		});		thread.start();	}}

这是我们通过多线程来获取到的A类的对象,来看下打印出的结果,这里并没有像上面的写法中显示的结果一样,而是创建了好多的实例对象

在学习了多线程的朋友应该了解到,其实所谓的并发,并不是真正的并发,而是通过时间片的轮转来使用cpu的资源,而这里的问题就出现在了判空处理的代码中

这里画个图来解释下:

解决这一问题我们需要用到了多线程中的synchronized关键字同步方法,这里要看清楚,因为这里的公共方法是static静态的方法,所以这里的同步监视器是指的A这个类,

这里使用同步方法可以看出是在操作系统中的临界资源,当一个数据正在被访问,会给这个数据加一把锁,有锁的数据只能同时被一个进行所访问,其他的线程只能等待,只有这个线程释放了这把锁其他的线程才可以访问,这样我下面这些代码在做判空处理的时候就不会出现错误。

class A{	//创建一个私有静态的类对象	private static A a = null;	//私有化构造	private A() {		System.out.println("创建了一个A的实例对象");	}	//提供一个共有的可以返回类对象的方法	public synchronized static A getSingleton() {		if(a == null) {			a = new A();		}		return a;	}}

同样这里使用for循环在多线程下来检测下是否可以

public static void main(String[] args) {	for(int i = 0 ;i <500;i++) {		Thread thread = new Thread(()->{			A.getSingleton();		});		thread.start();	}}

看下结果,这中情况只会出现在懒汉式的写法中,饿汉式是不会出现的。只要加个同步方法就可以了(这里的同步静态方法监视器是类)

 

转载于:https://www.cnblogs.com/mCarrYoung/p/11062200.html

你可能感兴趣的文章
Perl 三种时间time,localtime,gmttime
查看>>
Vue入门(一)-Vue实现选项卡效果
查看>>
vue如何在组件内部做整个页面的遮罩层
查看>>
python基础学习笔记——Python基础教程(第2版 修订版)第15章(python和万维网)
查看>>
jQuery获取和设置disabled属性、背景图片路径
查看>>
php多维数组的取值基础知识
查看>>
Sym-GAN
查看>>
查询tensorflow中的函数用法
查看>>
杨玲 - 杨蓉庆 - 张燕 201771010133《面向对象程序设计(java)》第十四周学习总结...
查看>>
实用爬虫-01-检测爬虫的 IP
查看>>
081 Region的预分区
查看>>
Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---命令模式之SimpleRemoteControlTest [转]...
查看>>
用C++结束进程(恶搞你的计算机!!!!)
查看>>
Ubuntu14.04 安装 Sublime Text 3
查看>>
Spring入门之setter DI注入
查看>>
Sharepoint的处理IIS(Process)与账户处理模型
查看>>
C#执行DOS命令(CMD命令) (转)
查看>>
IDEA的常见的设置和优化(功能)
查看>>
TestNG 入门教程
查看>>
UVA-227 Puzzle(傻屌之王)
查看>>