设计模式浅谈之单例模式
发布日期:11-05-07 01:11 文章来源:互联网
【分享】在Java 的单例模式中,有两种实现方式,懒汉式与饿汉式。
单例模式实现之饿汉式
|-单例类Songleton /**
* 单例模式实现之一饿汉式
*
* 一开始就创建Singleton的对象并实例化
*
*/
class Singleton
{
// 创建一个Signleton实例对象,用来存储创建好的实例
private static Singleton singleton = new Singleton();
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 返回实例对象
return singleton;
}
}复制代码|-测试类 public class SingletonDemo
{
public static void main(String[] args)
{
// 创建Singleton实例对象
Singleton singleton01 = Singleton.getInstance();
Singleton singleton02 = Singleton.getInstance();
// 判断两个实例对象是否是同一个
if (singleton01 == singleton02)
{
//相同打印"The Same Object!"
System.out.println("The Same Object!");
}
else
{
//不相同打印"The DifferentObject!"
System.out.println("The Different Object!");
}
}
}复制代码|-测试结果 The Same Object!复制代码从测试的结果可以看出,获得Singleton对象是同一对象。
|-饿汉式程序调用顺序图
单例模式实现之懒汉式
|-单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话实例化
if (null == singleton)
{
singleton = new Singleton();
}
// 返回实例对象
return singleton;
}
}复制代码|-测试类与测试结果 和上面 单例模式实现之饿汉式的一样,达到了生成同一个Singleton的
对象。
|-懒汉式程序调用顺序图
以上两种实现方式均单线程的情况下,但是在多线程的情况下, 懒汉式就可能生成不止
一个Singleton对象。如下实例
单例模式实现之懒汉式(多线程)
|-单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 但时在多线程的时候,生成的可能就不是一个对象了
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话 实例化
if (null == singleton)
{
//捕捉异常
try
{
//对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long)(Math.random() * 1000));
singleton = new Singleton();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码加入了Thread.sleep()方法,让线程睡眠一段时间。|-线程类 //实现Runnable接口的线程类
class SingletonThread implements Runnable
{
//覆写Runnable接口中的run()方法
public void run()
{
//打印获取的Singleton对象地址信息
System.out.println(Singleton.getInstance());
}
}复制代码用于获取Singleton的对象。|-测试类 public class SingletonDemo
{
public static void main(String[] args)
{
// 创建两个匿名线程对象,并启动
new Thread(new SingletonThread()).start();
new Thread(new SingletonThread()).start();
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton03.Singleton@69b332
com.shengsiyuan.javalinux.singleton03.Singleton@173a10f复制代码结果显示生成的Singleton对象的内存地址不一样,即不是同一对象。说明在多线程的情
况下单例模式的懒汉式不能达到生成同一对象的目的。
单例模式实现之懒汉式改进(多线程)――使用synchronized修饰方法
对Singleton类进行改进,对getInstance()进行同步加锁,即使用synchronized关键字。
修改:单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 多线程的时候,对生成实例的getInstance()方法进行加锁
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 对此方法进行加锁,实现同步,来获取Sington实例对象
public static synchronized Singleton getInstance()
{
// 判断singleton 是否为null,是的话 实例化
if (null == singleton)
{
// 捕捉异常
try
{
// 对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long) (Math.random() * 1000));
singleton = new Singleton();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton04.Singleton@1b67f74
com.shengsiyuan.javalinux.singleton04.Singleton@1b67f74复制代码此时打印的结果是一致的,说明生成的Singleton对象是同一对象。
单例模式实现之懒汉式改进(多线程)――使用synchronized代码块
在getInstance()方法中使用同步代码块进行加锁。 /**
* 单例模式实现之一饿汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 多线程的时候,对生成实例的getInstance()方法进行加锁
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话实例化
if (null == singleton)
{
// 捕捉异常
try
{
// 对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long) (Math.random() * 1000));
//使用同步代码块,线程安全的创建实例
synchronized (Singleton.class)
{
//再次检查实例是否存在,不存在的话在创建实例
if (null == singleton)
singleton = new Singleton();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton05.Singleton@1a758cb
com.shengsiyuan.javalinux.singleton05.Singleton@1a758cb复制代码此时打印的结果是一致的,说明生成的Singleton对象是同一对象。
以上为我所理解的Java 设计模式中的单例模式。其中可能有不恰当的地方,望指教。
单例模式实现之饿汉式
|-单例类Songleton /**
* 单例模式实现之一饿汉式
*
* 一开始就创建Singleton的对象并实例化
*
*/
class Singleton
{
// 创建一个Signleton实例对象,用来存储创建好的实例
private static Singleton singleton = new Singleton();
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 返回实例对象
return singleton;
}
}复制代码|-测试类 public class SingletonDemo
{
public static void main(String[] args)
{
// 创建Singleton实例对象
Singleton singleton01 = Singleton.getInstance();
Singleton singleton02 = Singleton.getInstance();
// 判断两个实例对象是否是同一个
if (singleton01 == singleton02)
{
//相同打印"The Same Object!"
System.out.println("The Same Object!");
}
else
{
//不相同打印"The DifferentObject!"
System.out.println("The Different Object!");
}
}
}复制代码|-测试结果 The Same Object!复制代码从测试的结果可以看出,获得Singleton对象是同一对象。
|-饿汉式程序调用顺序图
![Java 设计模式浅谈之单例模式](http://images.24xuexi.com/study/all/201105/07/20110507131191763.jpg)
单例模式实现之懒汉式
|-单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话实例化
if (null == singleton)
{
singleton = new Singleton();
}
// 返回实例对象
return singleton;
}
}复制代码|-测试类与测试结果 和上面 单例模式实现之饿汉式的一样,达到了生成同一个Singleton的
对象。
|-懒汉式程序调用顺序图
![Java 设计模式浅谈之单例模式](http://images.24xuexi.com/study/all/201105/07/20110507131179073.jpg)
以上两种实现方式均单线程的情况下,但是在多线程的情况下, 懒汉式就可能生成不止
一个Singleton对象。如下实例
单例模式实现之懒汉式(多线程)
|-单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 但时在多线程的时候,生成的可能就不是一个对象了
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话 实例化
if (null == singleton)
{
//捕捉异常
try
{
//对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long)(Math.random() * 1000));
singleton = new Singleton();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码加入了Thread.sleep()方法,让线程睡眠一段时间。|-线程类 //实现Runnable接口的线程类
class SingletonThread implements Runnable
{
//覆写Runnable接口中的run()方法
public void run()
{
//打印获取的Singleton对象地址信息
System.out.println(Singleton.getInstance());
}
}复制代码用于获取Singleton的对象。|-测试类 public class SingletonDemo
{
public static void main(String[] args)
{
// 创建两个匿名线程对象,并启动
new Thread(new SingletonThread()).start();
new Thread(new SingletonThread()).start();
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton03.Singleton@69b332
com.shengsiyuan.javalinux.singleton03.Singleton@173a10f复制代码结果显示生成的Singleton对象的内存地址不一样,即不是同一对象。说明在多线程的情
况下单例模式的懒汉式不能达到生成同一对象的目的。
单例模式实现之懒汉式改进(多线程)――使用synchronized修饰方法
对Singleton类进行改进,对getInstance()进行同步加锁,即使用synchronized关键字。
修改:单例类Songleton /**
* 单例模式实现之一懒汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 多线程的时候,对生成实例的getInstance()方法进行加锁
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 对此方法进行加锁,实现同步,来获取Sington实例对象
public static synchronized Singleton getInstance()
{
// 判断singleton 是否为null,是的话 实例化
if (null == singleton)
{
// 捕捉异常
try
{
// 对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long) (Math.random() * 1000));
singleton = new Singleton();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton04.Singleton@1b67f74
com.shengsiyuan.javalinux.singleton04.Singleton@1b67f74复制代码此时打印的结果是一致的,说明生成的Singleton对象是同一对象。
单例模式实现之懒汉式改进(多线程)――使用synchronized代码块
在getInstance()方法中使用同步代码块进行加锁。 /**
* 单例模式实现之一饿汉式
*
* 当需要实例对象的时候再去生成对象进行实例化
*
* 多线程的时候,对生成实例的getInstance()方法进行加锁
*
*/
class Singleton
{
// 声明一个Signleton变量,用来存储创建好的实例
private static Singleton singleton = null;
// 将构造方法进行私有化
private Singleton()
{
// 待执行代码
}
// 获取Sington实例对象
public static Singleton getInstance()
{
// 判断singleton 是否为null,是的话实例化
if (null == singleton)
{
// 捕捉异常
try
{
// 对线程进行休眠,休眠时间是随机生成的
Thread.sleep((long) (Math.random() * 1000));
//使用同步代码块,线程安全的创建实例
synchronized (Singleton.class)
{
//再次检查实例是否存在,不存在的话在创建实例
if (null == singleton)
singleton = new Singleton();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// 返回实例对象
return singleton;
}
}复制代码|-测试结果 com.shengsiyuan.javalinux.singleton05.Singleton@1a758cb
com.shengsiyuan.javalinux.singleton05.Singleton@1a758cb复制代码此时打印的结果是一致的,说明生成的Singleton对象是同一对象。
以上为我所理解的Java 设计模式中的单例模式。其中可能有不恰当的地方,望指教。