饿汉式和懒汉式(单例模式详解)
来源:互联网 发布:左脑右脑 知乎 编辑:程序博客网 时间:2024/05/29 12:15
单例的目的是保证某个类仅有一个实例。当有某些类创建对象内存开销较大时可以考虑使用该模式。单例模式又分为饿汉式和懒汉式。下面分别说明:
1.饿汉式。顾名思义,该模式在类被加载时就会实例化一个对象。具体代码如下:
public class Person {
//饿汉式单例
private static Person person = new Person();
private Person(){}
public static Person getInstance(){
return person;
}
}
该模式能简单快速的创建一个单例对象,而且是线程安全的(只在类加载时才会初始化,以后都不会)。但它有一个缺点,就是不管你要不要都会直接创建一个对象,会消耗一定的性能(当然很小很小,几乎可以忽略不计,所以这种模式在很多场合十分常用而且十分简单)
2.懒汉式。该模式只在你需要对象时才会生成单例对象(比如调用getInstance方法)
public class User {
//懒汉式单例,只有在调用getInstance时才会实例化一个单例对象
public static User user;
private User(){
}
public static User getInstance(){
if(user==null){ //step 1.
user = new User(); //step 2
}
return user;
}
}
看上去,这段代码没什么明显问题,但它不是线程安全的。假设当前有N个线程同时调用getInstance()方法,由于当前还没有对象生成,所以一部分同时都进入step 2,
那么就会由多个线程创建多个多个user对象。
解决办法:使用synchronized关键字。经改造上面代码展示如下:
public class User {
//懒汉式单例,只有在调用getInstance时才会实例化一个单例对象
public static User user;
public static Integer key = new Integer(4); //作为一个锁
private User(){
}
public static User getInstance(){
//先判断该user变量是否为空,入股为空,进入同步代码块,该步假设为step1
if(user == null){ //step 1 //想象一下,如果不判断,那么每次访问这个方法不管该对象是否已经创建都要进入同步代码块,线程数一多,资源消耗也是非常巨大的。
synchronized (key) {
//由于可能多个线程都进入了step1,由于锁定机制,一个线程进入该代码块时,其他线程
//仍在排队进入该代码块,如果不做判断,当前线程即使创造了实例,下一个线程也不知道,就会继续创建一个实例
if(user==null){
user = new User();
}
}
}
return user;
}
}
通过上面的锁机制同步代码块就可以写出线程安全的懒汉式单例。
- 饿汉式和懒汉式(单例模式详解)
- 单例模式-饿汉式和懒汉式
- 单例模式(懒汉式和饿汉式)
- 单例模式(懒汉式和饿汉式)
- 设计模式-单例模式之饿汉式和懒汉式
- 设计模式------单例模式之饿汉式和懒汉式
- 单例模式两种模式--饿汉式和懒汉式
- 单例模式的懒汉式和饿汉式
- Java单例模式:饿汉式和懒汉式的实现
- 单例模式的懒汉式和饿汉式
- Java单例模式:饿汉式和懒汉式的实现
- Java单例模式:饿汉式和懒汉式的实现
- Java单例模式:饿汉式和懒汉式的实现
- 单例模式的懒汉式和饿汉式
- 黑马程序员-单例设计模式:懒汉式和饿汉式
- 单例模式中,懒汉式和饿汉式的区别
- 单例模式(懒汉式和饿汉式)
- 单例设计模式(饿汉式和懒汉式)
- ubuntu-16.4TLS安装QQ
- intellij idea 2016版破解方法
- AOP调用注意点
- 第一章上机练习
- Ubuntu安装出现左上角光标一直闪解决方式
- 饿汉式和懒汉式(单例模式详解)
- 系统攻防安全入门级教程
- 百度云盘破解限速|个人值得拥有
- Oracle在中文环境下出现乱码解决办法
- Linux配置无线网卡驱动实现无线上网
- Putty SSH简单使用
- servlet规范之ServletRequest中getAttribute和getParameter方法的区别
- Oracle 11g 7个压缩包说明
- Android中的序列化Serializable和Parcelable