黑马程序员技术交流社区
标题:
Java中的单例设计模式
[打印本页]
作者:
Enhon1992
时间:
2015-6-7 18:35
标题:
Java中的单例设计模式
在Java开发中,有时我们会有这样的需求就是在描述一个类的时候,要求我们必须保证这个类的对象在内存中只会存在一个,就是保存对象在内存中的唯一性,那我们在设计这个类的时候,就应该使用单例设计模式。Java中常用的单例设计模式 有两种,懒汉式,饿汉式。采用单例设计模式设计的类有以下特点:
1,在该类中需要定义一个该类类型的静态字段。
2,将该类的构造函数私有化。
3,对外提供能够获取该类实例的静态工厂方法。
懒汉式:
class Single
{
//定义一个静态的私有字段
private static Single s=null;
//定义静态工厂方法 返回该类的实例
public static Single getSingleInstance()
{
if(s==null)
{
s=new Single();
}
return s;
}
//私化构造函数
private Single()
{
}
}
复制代码
饿汉式:
class Single
{
//定义一个静态的私有字段, 并在类加载时候就创建了该类的实例
private static final Single s=new Single();
//定义静态工厂方法 返回该类的实例
public static Single getSingleInstance()
{
return s;
}
//私化构造函数
private Single()
{
}
}
复制代码
懒汉式和饿汉式的区别:
1,饿汉式是在类加载的时候内存中就创建了对象,而懒汉式 是在调用该类的静态工厂方法的时候才创建对象。
2,饿汉式 是线程安全的,而懒汉式线程不安全。
分析懒汉式产生线程安全问题的原因:
当多个线程同时 执行懒汉式中的getSingleInstance()方法的时,这多个线程都会访问共享数据 静态私有字段s(因为该字段是静态的 所以是共享数据),并且操作共享数据的代码是多行,所以会产生线程安全问题,这样就保证不了该类在内存中的对象的唯一性。
解决懒汉式线程安全问题:
class Single
{
//定义一个静态的私有字段
private static Single s=null;
//定义静态工厂方法 返回该类的实例
public static Single getSingleInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
{
s=new Single();
}
}
}
return s;
}
//私化构造函数
private Single()
{
}
}
复制代码
上面两种单例模式,能够保证对象的唯一性的根本原因就是 ,将构造函数私有化,不允许在该类的外部调用构造函数创建对象。要是我们利用反射技术Single.class.getDeclaredConstructor(null).setAccessible(true); 来获取到该类构造器对象 ,那么这样的话就保证不了对象的唯一性。所以说我们要是利用反射技术的话,上面两种单例模式就会失效。
PS:如果一个枚举类的枚举值只有一个话,这个枚举类可以当做单例设计模式使用。
作者:
storer
时间:
2015-6-7 19:05
后面的没有听懂啊,还要继续学习
作者:
Enhon1992
时间:
2015-6-7 19:24
storer 发表于 2015-6-7 19:05
后面的没有听懂啊,还要继续学习
你说反射那块啊!
作者:
feng0606
时间:
2015-6-7 20:04
这块自学一直没怎么学懂,还得继续研究才行.
作者:
岁月无情
时间:
2015-6-8 00:33
很不错啊
作者:
乐成
时间:
2015-6-8 20:01
饿汉式单例设计模式存在线程安全问题,应该双重判断,利用同步代码块的形式来保证多线程下饿汉式的安全问题
下面这个是我写的代码,不知大家认同不,小菜鸟,写的不对的,望大家指教
package com.itheima;
/**
* 题目8:编写一个延迟加载的单例设计模式。
* @author xiaocheng
*
*/
public class Test8 {
/**
* @param args
*/
public static void main(String[] args) {
/**
* 通过本类对象调用getSingleInstance()方法来获取本类对象
* 而不能通过new的方式来产生本类对象,保证了本类对象的唯一性
*/
Single s1 = Single.getSingleInstance(); //通过本类对象调用getSingleInstance()方法来获取本类对象s1
Single s2 = Single.getSingleInstance(); //通过本类对象调用getSingleInstance()方法来获取本类对象s2
//如果打印结果为true,则说明s1和s2是同一个对象,如果打印结果为false,则说明s1和s2是两个不同的对象
System.out.println("s1==s2:"+(s1==s2));
}
}
/**
* 定义一个延迟加载的单例设计模式
* 单例设计模式的实现:
* 1.构造函数私有化
* 2.在本类中创建一个私有的本类对象
* 3.提供一个方法可以获取到本类对象
* 单例设计模式分为懒汉式和饿汉式
* 其中延迟加载属于懒汉式
* 懒汉式在多线程中容易出现安全问题,所以需要使用synchronized同步代码块,保证多线程的安全问题
*/
class Single{
private Single(){} //构造函数私有化
private static Single s = null; //在本类中创建一个私有的本类对象
public static Single getSingleInstance()
{
/**
* 因为懒汉式在多线程中容易出现安全问题,
* 所以需要使用synchronized给代码块加锁,保证多线程的安全问题
* 这里的锁是本类的字节码文件Single.class
*/
if(s==null)
{
synchronized (Single.class) {
s = new Single();
}
}
return s;
}
}
作者:
坏坏总是我
时间:
2015-6-8 21:38
很给力 ,赞一个
作者:
wwb1105
时间:
2015-6-8 21:39
学习了~~~~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2