java单例模式【csdn-炸死特】

概念:
  java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
  单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。
  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer
Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

首先看一个经典的单例实现。

[java] view plaincopyprint?

  1. public class Singleton {

  2. private static Singleton uniqueInstance = null;
  3. private Singleton() {

  4. // Exists only to defeat instantiation.

  5. }
  6. public static Singleton getInstance() {

  7. if (uniqueInstance == null) {

  8. uniqueInstance = new Singleton();

  9. }

  10. return uniqueInstance;

  11. }

  12. // Other methods...

  13. }

public class Singleton {
private static Singleton uniqueInstance = null;

private Singleton() {
// Exists only to defeat instantiation.
}

public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。

[java] view plaincopyprint?

  1. package jason.single;
  2. public class TestStream {

  3. String name = null;
  4. public String getName() {

  5. return name;

  6. }
  7. public void setName(String name) {

  8. this.name = name;

  9. }
  10. private TestStream() {

  11. }
  12. private static TestStream ts1 = null;
  13. public static TestStream getTest() {

  14. if (ts1 == null) {

  15. ts1 = new TestStream();

  16. }

  17. return ts1;

  18. }
  19. public void printInfo() {

  20. System.out.println("the name is " + name);

  21. }
  22. }

package jason.single;

public class TestStream {
String name = null;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

private TestStream() {
}

private static TestStream ts1 = null;

public static TestStream getTest() {
if (ts1 == null) {
ts1 = new TestStream();
}
return ts1;
}

public void printInfo() {
System.out.println("the name is " + name);
}

}

[java] view plaincopyprint?

  1. package jason.single;
  2. public class TMain {

  3. public static void main(String[] args){

  4. TestStream ts1 = TestStream.getTest();

  5. ts1.setName("jason");

  6. TestStream ts2 = TestStream.getTest();

  7. ts2.setName("0539");
  8. ts1.printInfo();

  9. ts2.printInfo();
  10. if(ts1 == ts2){

  11. System.out.println("创建的是同一个实例");

  12. }else{

  13. System.out.println("创建的不是同一个实例");

  14. }

  15. }

  16. }

package jason.single;

public class TMain {
public static void main(String[] args){
TestStream ts1 = TestStream.getTest();
ts1.setName("jason");
TestStream ts2 = TestStream.getTest();
ts2.setName("0539");

ts1.printInfo();
ts2.printInfo();

if(ts1 == ts2){
System.out.println("创建的是同一个实例");
}else{
System.out.println("创建的不是同一个实例");
}
}
}

运行结果:

结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。

1.饿汉式单例类

[java] view plaincopyprint?

  1. //饿汉式单例类.在类初始化时,已经自行实例化

  2. public class Singleton1 {

  3. //私有的默认构造子

  4. private Singleton1() {}

  5. //已经自行实例化

  6. private static final Singleton1 single = new Singleton1();

  7. //静态工厂方法

  8. public static Singleton1 getInstance() {

  9. return single;

  10. }

  11. }

//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}

2.懒汉式单例类

[java] view plaincopyprint?

  1. //懒汉式单例类.在第一次调用的时候实例化

  2. public class Singleton2 {

  3. //私有的默认构造子

  4. private Singleton2() {}

  5. //注意,这里没有final

  6. private static Singleton2 single=null;

  7. //静态工厂方法

  8. public synchronized  static Singleton2 getInstance() {

  9. if (single == null) {

  10. single = new Singleton2();

  11. }

  12. return single;

  13. }

  14. }

//懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}
//注意,这里没有final
private static Singleton2 single=null;
//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}

[java] view plaincopyprint?

  1. import java.util.HashMap;

  2. import java.util.Map;

  3. //登记式单例类.

  4. //类似Spring里面的方法,将类名注册,下次从里面直接获取。

  5. public class Singleton3 {

  6. private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();

  7. static{

  8. Singleton3 single = new Singleton3();

  9. map.put(single.getClass().getName(), single);

  10. }

  11. //保护的默认构造子

  12. protected Singleton3(){}

  13. //静态工厂方法,返还此类惟一的实例

  14. public static Singleton3 getInstance(String name) {

  15. if(name == null) {

  16. name = Singleton3.class.getName();

  17. System.out.println("name == null"+"--->name="+name);

  18. }

  19. if(map.get(name) == null) {

  20. try {

  21. map.put(name, (Singleton3) Class.forName(name).newInstance());

  22. } catch (InstantiationException e) {

  23. e.printStackTrace();

  24. } catch (IllegalAccessException e) {

  25. e.printStackTrace();

  26. } catch (ClassNotFoundException e) {

  27. e.printStackTrace();

  28. }

  29. }

  30. return map.get(name);

  31. }

  32. //一个示意性的商业方法

  33. public String about() {

  34. return "Hello, I am RegSingleton.";

  35. }

  36. public static void main(String[] args) {

  37. Singleton3 single3 = Singleton3.getInstance(null);

  38. System.out.println(single3.about());

  39. }

  40. }

java单例模式【csdn-炸死特】

时间: 2024-10-13 19:32:06

java单例模式【csdn-炸死特】的相关文章

炉石传说 疯狂爆破者空场炸死2个精灵龙的概率

背景介绍 炉石传说中,有一张卡牌叫疯狂爆破者,功能为造成6点伤害,随机分配给其他角色(包括英雄和随从). 这经常能造成一些意想不到的效果,比如对方空场有2个精灵龙,如果能直接炸死,则能造成巨大的优势,所以本文将要分析一下空场炸死对方2个精灵龙的概率. 分析 1. 使用程序进行模拟 #include "stdio.h" #include <cmath> #include <stdlib.h> #include <algorithm> #include

【深入】java 单例模式(转)

[深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便萌生了写这篇文章的念头.企图把这个单例说透,说深入.但愿我不会做的太差. 首先来看一个典型的实现: 1 /** 2 * 基础的单例模式,Lazy模式,非线程安全 3 * 优点:lazy,初次使用时实例化单例,避免资源浪费 4 * 缺点:1.lazy,如果实例初始化非常耗时,初始使用时,可能造成性能问

JAVA单例模式的实践

单例模式是JAVA设计模式中最常用.最重要的设计模式之一. 最简单的写法是: public class TestSingleton { private static String ourInstance = null; //私有化构造器 private TestSingleton() { } //提供静态方法给外部访问 public static String getOurInstance(){ if(ourInstance == null){ ourInstance="单例模式赋值成功!!!&

Java 单例模式探讨

以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. 总结一下我所知道的单例模式实现方式: 1.预先加载法 Java代码 class S1 { private S1() { System.out.println("ok1"); } private static S1 instance = new S1(); public static S1

【转】10个关于java单例模式的面试问题

10 interview question on Singleton Pattern in Java Question starts with What is Singleton class? Have you used Singleton before? Singleton is a class which has only one instance in whole application and provides a getInstance() method to access the s

你所知道的Java单例模式并不是单例模式

当我们搜索单例模式的时候,能看到很多例子,什么懒汉式.饿汉式,大概如下: public class Singleton { private static Singleton instance=null; private Singleton(){ System.out.println("Singleton..init..."); } public static Singleton getInstance(){ if(instance==null){ instance=new Single

is高级头目被炸死跳槽不足1个月 网友:叛徒必须死

英媒9日报道在阿富汗一名is高级头目被炸死.据悉这名被炸死的is高级头目1月份与塔利班决裂,宣布效忠IS.但是倒戈不足一个月就被炸死.有网友感慨果然是叛徒必须死.也有网友认为估计是被塔利班卖给阿富汗政府了.is高级头目被炸死后,IS向阿富汗扩张步伐受到影响.据悉“伊斯兰国”已与阿富汗塔利班多次发生冲突,至少十几人死亡. 据英国广播公司(BBC)2月9日报道,阿富汗赫尔曼德省(Helmand)警方称,阿富汗境内进行的无人机轰炸行动杀死了一名最近刚宣称将效忠“伊斯兰国”(简称IS)的军事指挥官. 报

深入Java单例模式(转)

深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下. 所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在.就像是Java Web中的application,也就是提供了一个全局变量,用处相当广泛,比如保存全局数据,实现全局性的操作等. 1. 最简单的实现 首先,能够想到的最简单的实现是,把类

java单例模式案例

</pre>单例模式是一种常见的设计模式,一般有三种方式,单例模式具有如下特点:<p></p><p><span style="white-space:pre">1.在类的属性中,自己初始化一个静态的私有的类实例<span style="white-space:pre"></span>2.将自己的构造方法写成private的方式,拒绝其他类或者操作再次使用构造函数将单例类再次实例化&l