1.java中的单例模式的代码怎么写
我从我的博客里把我的文章粘贴过来吧,对于单例模式模式应该有比较清楚的解释:单例模式在我们日常的项目中十分常见,当我们在项目中需要一个这样的一个对象,这个对象在内存中只能有一个实例,这时我们就需要用到单例。
一般说来,单例模式通常有以下几种:1.饥汉式单例 public class Singleton { private Singleton(){}; private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } } 这是最简单的单例,这种单例最常见,也很可靠!它有个唯一的缺点就是无法完成延迟加载——即当系统还没有用到此单例时,单例就会被加载到内存中。在这里我们可以做个这样的测试:将上述代码修改为:public class Singleton { private Singleton(){ System.out.println("createSingleton"); }; private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } public static void testSingleton(){ System.out.println("CreateString"); } } 而我们在另外一个测试类中对它进行测试(本例所有测试都通过Junit进行测试) public class TestSingleton { @Test public void test(){ Singleton.testSingleton(); } } 输出结果:createSingleton CreateString 我们可以注意到,在这个单例中,即使我们没有使用单例类,它还是被创建出来了,这当然是我们所不愿意看到的,所以也就有了以下一种单例。
2.懒汉式单例 public class Singleton1 { private Singleton1(){ System.out.println("createSingleton"); } private static Singleton1 instance = null; public static synchronized Singleton1 getInstance(){ return instance==null?new Singleton1():instance; } public static void testSingleton(){ System.out.println("CreateString"); } } 上面的单例获取实例时,是需要加上同步的,如果不加上同步,在多线程的环境中,当线程1完成新建单例操作,而在完成赋值操作之前,线程2就可能判 断instance为空,此时,线程2也将启动新建单例的操作,那么多个就出现了多个实例被新建,也就违反了我们使用单例模式的初衷了。我们在这里也通过一个测试类,对它进行测试,最后面输出是 CreateString 可以看出,在未使用到单例类时,单例类并不会加载到内存中,只有我们需要使用到他的时候,才会进行实例化。
这种单例解决了单例的延迟加载,但是由于引入了同步的关键字,因此在多线程的环境下,所需的消耗的时间要远远大于第一种单例。我们可以通过一段测试代码来说明这个问题。
public class TestSingleton { @Test public void test(){ long beginTime1 = System.currentTimeMillis(); for(int i=0;i<100000;i++){ Singleton.getInstance(); } System.out.println("单例1花费时间:"+(System.currentTimeMillis()-beginTime1)); long beginTime2 = System.currentTimeMillis(); for(int i=0;i<100000;i++){ Singleton1.getInstance(); } System.out.println("单例2花费时间:"+(System.currentTimeMillis()-beginTime2)); } } 最后输出的是:单例1花费时间:0 单例2花费时间:10 可以看到,使用第一种单例耗时0ms,第二种单例耗时10ms,性能上存在明显的差异。为了使用延迟加载的功能,而导致单例的性能上存在明显差异,是不是会得不偿失呢?是否可以找到一种更好的解决的办法呢?既可以解决延迟加载,又不至于性能损耗过多,所以,也就有了第三种单例:3.内部类托管单例 public class Singleton2 { private Singleton2(){} private static class SingletonHolder{ private static Singleton2 instance=new Singleton2(); } private static Singleton2 getInstance(){ return SingletonHolder.instance; } } 在这个单例中,我们通过静态内部类来托管单例,当这个单例被加载时,不会初始化单例类,只有当getInstance方法被调用的时候,才会去加载 SingletonHolder,从而才会去初始化instance。
并且,单例的加载是在内部类的加载的时候完成的,所以天生对线程友好,而且也不需要 synchnoized关键字,可以说是兼具了以上的两个优点。4.总结 一般来说,上述的单例已经基本可以保证在一个系统中只会存在一个实例了,但是,仍然可能会有其他的情况,导致系统生成多个单例,请看以下情况:public class Singleton3 implements Serializable{ private Singleton3(){} private static class SingletonHolder{ private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance(){ return SingletonHolder.instance; } } 通过一段代码来测试:@Test public void test() throws Exception{ Singleton3 s1 = null; Singleton3 s2 = Singleton3.getInstance(); //1.将实例串行话到文件 FileOutputStream fos = new FileOutputStream("singleton.txt"); ObjectOutputStream oos =new ObjectOutputStream(fos); oos.writeObject(s2); oos.flush(); oos.close(); //2.从文件中读取出单例 FileInputStream fis = new FileInputStream("singleton.txt"); ObjectInputStream ois = new ObjectInputStream(fis); s1 = (Singleton3) ois.readObject(); if(s。
2.如何写一个简单的单例模式
一、基本的实现思路:
单例的实现主要是通过以下两个步骤:
1、将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;
2、在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。
二、示范如下:
1、枚举实现单例:
2、懒汉式线程不安全:
3、懒汉式线程安全:
4、饿汉式:
5、双重校验锁:
6、静态内部类:
扩展资料:
一、单列模式简介:
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
二、懒汉与饿汉:
1、懒汉方式:指全局的单例实例在第一次被使用时构建。
2、饿汉方式:指全局的单例实例在类装载时构建。
三、单例模式的三要点:
1、某个类只能有一个实例。
2、它必须自行创建这个实例。
3、它必须自行向整个系统提供这个实例。
四、优缺点:
1、优点:
①实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
②灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程。
2、缺点:
①开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
②可能的开发混淆:使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
③对象生存期:不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。
参考资料:百度百科单列模式
3.如何写一个标准的Java单例模式
一般Singleton模式通常有两种形式:第一种形式:也是常用的形式。
publicclassSingleton{=null;privateSingleton(){//dosomething}//这个方法比下面的有所改进,不用每次都进行生成对象,只是第一次使用时生成实例,提高了效率(){if(instance==null){instance=newSingleton();}returninstance;}}第二种形式:publicclassSingleton{//在自己内部定义自己的一个实例,只供内部调用=newSingleton();privateSingleton(){//dosomething}//这里提供了一个供外部访问本class的静态方法,可以直接访问(){returninstance;}}。
4.如何用Java实现单例模式
单例模式:就是一个类仅创建一个对象;
public class Singleton {
private static volatile Singleton singleton = null;
private Singleton(){}// 构造方法
public static Singleton getSingleton(){// 单例模式
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
5.在java中,singleton是什么啊
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第二种形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些
6.java单例模式
当一个class被new也就是实例化的时候,调用构造方法的同时也会实例化成员变量,你这里定义的Singleton s=new Singleton()相当于定义了一个名为s的Singleton类型的参数,初始值为new Singleton(); 所以肯定会执行的。 正确的singleton模式其中之一:
class Singleton {
private static Singleton s;
private Singleton(){ }
public static Singleton getInstance()
{
if(s==null) s=new Singleton();
return s;
}
}
7.JAVA单例模式的几种实现方法
JAVA 单例模式的几种实现方法1.饿汉式单例类 package pattern.singleton;// 饿汉式单例类.在类初始化时,已经自行实例化 public class Singleton1 {// 私有的默认构造子 private Singleton1() {}// 已经自行实例化 private static final Singleton1 single= new Singleton1();// 静态工厂方法 public static Singleton1 getInstance() { return single; } }2.懒汉式单例类 package pattern.singleton;// 懒汉式单例类.在第一次调用的时候实例化 public class Singleton2 {// 私有的默认构造子 private Singleton2() {}// 注意,这里没有 final private static Singleton2 single;// 只实例化一次 static { single= new Singleton2(); }// 静态工厂方法 public synchronized static Singleton2 getInstance() { if(single== null) { single= new Singleton2(); } return single; } } 在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境。
有些设计师在这里建议使用所谓的" 双重检查成例".必须指出的是," 双重检查成例" 不可以在 Java 语言中使用。不十分熟悉的读者,可以看看后面给出的小节。
同 样,由于构造子是私有的,因此,此类不能被继承。饿汉式单例类在自己被加载时就将自己实例化。
即便加载器是静态的,在饿汉 式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。
从速度和反应时间角度来讲,则 比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处 理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源 初始化很有可能耗费时间。
这意味着出现多线程同时首次引用此类的机率变得较大。饿汉式单例类可以在 Java 语言内实现,但不易在 C++ 内实现,因为静态初始化在 C++ 里没有固定的顺序,因而静态的 m_instance 变量的初始化与类的加载顺序没有保证,可能会出问题。
这就是为什么 GoF 在提出单例类的概念时,举的例子是懒 汉式的。他们的书影响之大,以致 Java 语言中单例类的例子也大多是懒汉式的。
实际上,本书认为饿汉式单例类更符合 Java 语 言本身的特点。3.登记式单例类.package pattern.singleton; import java.util.HashMap; import java.util.Map;// 登记式单例类.// 类似 Spring 里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 { private static Map
转载请注明出处育才学习网 » 单例模式java主函数怎么写