Java单例模式详解
来源:互联网 发布:oracle导入数据 编辑:程序博客网 时间:2024/04/30 06:00
要解决的问题
让一个类在内存中只有一个对象。
问题的由来
1.对于系统中的某些类来说只有一个实例很重要。
windows中只能打开一个任务管理器窗口。如果不使用机制对窗口对象进行唯一化,就会有我每点击一下按钮就出现一个任务管理器窗口这样的现象。如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符。
2.对于一些需要频繁创建的对象,用单例模式可以节约系统资源。
如何保证对象的唯一性
1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
2.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三步怎么用代码实现?
1.将构造函数私有化
2.在类中创建一个本类对象
3.提供一个方法可以获取到该对象。
饿汉式单例模式
class Single(){ private Singel(){}//将构造函数私有化 private static Single s=new Singel(); public static Singel getInstance() { return s; }}class SingleDemo{ public static void main(String[] args) { Single ss=Single.getInstance(); Single sss=Single.getInstance(); }}
先将构造函数私有化,这样在其他类中就不能使用new来创建他的对象。
创建一个Single类型的变量s来存储创建的Single对象,这个变量不必让外界知道,所以加上private修饰符。
private Singel s=new Singel();
创建一个公开的方法来返回这个对象
public Singel getInstance(){ return s;}
方法要么通过对象来调用,要么通过类名来调用。现在不能创建对象了,只能通过类名调用。所以这个方法应该静态方法。
在本类中静态方法只能访问静态成员,所以s也应该为静态的。
第一调用Single.getInstance();的时候,先加载类,创建对象,将对象的地址赋给s,再调用getInstance方法再将地址赋给ss。
第二次调用的时候,内存中已经存在s了,直接将地址赋给sss就行了。(这就省去了频繁创建对象的过程)。
光写这几句话没什么意义,对事物该怎么描述的时候还怎么描述,只是当需要保证事物的对象在内存中唯一时,将这三步加上即可。
懒汉式单例模式
class Single{ private Single(){} private static Single s=null; public static Single getInstance() { if(s==null) s=new Single(); return s; }}
这种写法,当一个程序来调用,不会出现问题。但当多个程序调用的时候就可能出现问题。
比如A程序在执行了if(s==null)后,判断为null,本来应该接着执行,但cpu又去执行别的程序了(cup一个时刻只能执行一个程序,只不过是cup切换程序的速度很快,用户感觉不到)。
之后B在执行了if(s==null)后,判断为null,本来应该接着执行,cup又切换到了A程序接着往下执行,创建了Single对象。之后cup又切换到了B,B接着执行,又创建了一个对象。这时候对象已经不唯一了。
class Single{ private Single(){} private static Single s=null; public static synchronized Single getInstance() { if(s==null) s=new Single(); return s; }}
可以添加synchronized关键字来吧这段程序锁起来,即使A程序执行到if(s==null),cpu切换了出去。因为加了锁,B也进不来。
但是这时程序的效率就低了,不管s是否为null,之前我都要判断是否锁着呢。
class Single{ private Single(){} private static Single s=null; public static Single getInstance() { if(s==null) { synchronized(Single.class) { if(s==null) s=new Single(); } } return s; }}
这样为s为空的时候才判断锁,减少了判断次数。
总结
饿汉式是Single类一进内存就已经创建好了对象。
懒汉式(也叫对象的延迟加载),在Single进内存的时候,对象还没有存在,只有调用了getInstance方法时,才建立了对象。
开发的时候用饿汉式,简单,安全(方法里就一句话,涉及不到多线程)。懒汉式面试的时候问的多。
玩儿单例模式就是为了用那个唯一对象,获取对象是首先要做的事,有了对象才能调用其它的方法。先创建后创建早晚都要加载。
- java 单例模式详解
- Java 单例模式详解
- java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解!
- JAVA单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- java单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- Java 单例模式详解
- 表达式合法判断(栈的使用)----去哪儿2016研发工程师编程题
- Effective C++_Item11笔记
- KMP
- Java的方向。。。
- POJ 3687 Labeling Balls 反向拓扑建图是个坑点
- Java单例模式详解
- leetcode 74. Search a 2D Matrix
- Memcached缓存
- HTML5audio duration返回NaN问题及歌曲切换总时间改变问题
- mybatis
- EJB 通过ANT卸载发布项目时 BUILD FAILED
- 使用NLPIR汉语分词系统进行分词
- Spring MVC入门
- mysqldump