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; }
} public class SingleTon {
private SingleTon() {
} private static class Inner {
int i = 0 ;
static SingleTon instance = new SingleTon();
} public static SingleTon getInstance() {
return Inner.instance;
}
}
2. 如果牵涉到数据库 用这个 可能并发的非常数量多的查询会引起效率的问题 所以需要synchronized
3. 显然代码有问题; int i 我猜是用来计数的 比如说这个SingleTon最多可以有多少个实例。但也可能不对 因为类名就叫SingleTon
private static Singleton instance;
public static Singleton getInstance() {
if (instance==null){
instance=new Singleton();
}
return instance;
}
效率没你的高,每次都要执行if条件判断,呵呵。2.sync了,表示同一时刻只能有一个地方调用getInstance方法,用来防止多线程同时访问,线性的使用这个类,一般用来对同一文件写入操作,或者对数据库表进行加锁的控制。3. 我土啊,居然没用过。。
第三种太麻烦,是 Effective Java 中说的方法,因为麻烦,也不用建议使用第一种,创建这样的对象对现代计算机来说几乎不存在效能损失。还有第四种,一般称为双重检查锁(double-checked locking),不过,很可惜在 JDK 5 之前完全无效,在高并发时候起不到单例的效果,可能会产生多个对象。JDK 5 之后必须在静态单例成员上加上 volatile 修饰双检锁才能生效。
第二种是 懒汉式
由于饿汉式是静态初始化方式,它是类一加载就实例化的对象,所以要提前占用资源。然后懒汉式又会面临这多线程访问的安全性问题,需要做双重锁定这样的处理才可以保证安全。
第三种使用静态内部类来实例化对象
比较少见。不过个人认为它应该也是懒汉式的一种拓展。
public class SingleTon {
private SingleTon() {
} private static class Inner {
int i = 0 ;
static {
System.out.println("inner");
}
static SingleTon instance = new SingleTon();
} public static SingleTon getInstance() {
System.out.println("getInstance");
return Inner.instance;
}
public static void main(String[] args){
SingleTon.getInstance();
SingleTon.getInstance();
}
}//打印结果
getInstance
inner
getInstance可见也是在加载内部类的时候才初始化。也是在需要的时候才实例化。
public class Singleton {
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance==null)
synchronized(this) {
if (instance==null){ instance=new Singleton();
}
}
return instance; }
}
这种最好了
*
* 单例模式
* @author
*
*/
public class Singleton
{
private static Singleton instance = null;
private Singleton()
{
super();
}
/**
* 很影响性能:每次调用getInstance方法的时候都必须获得Singleton的锁,
* 而实际上,当单例实例被创建以后,其后的请求没有必要再使用互斥机制了
* @return
*/
public static synchronized Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
/**
* 1. A、B线程同时进入了第一个if判断
*
* 2. A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();
*
* 3.
* 由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例
* ),然后A离开了synchronized块。
*
* 4.
* B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
*
* 5. 此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
*/
public static Singleton getInstance1() {
if (instance == null) {
synchronized (instance)
{
if (instance == null) {
return new Singleton();
}
}
}
return instance;
}
/**
* JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,
* JVM能够帮我们保证instance只被创建一次 ,
* 并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心3.2中的问题。
* 此外该方法也只会在第一次调用的时候使用互斥机制,这样就解决了3
* .1中的低效问题。最后instance是在第一次加载SingletonContainer类时被创建的,
* 而SingletonContainer类则在调用getInstance方法的时候才会被加载,因此也实现了惰性加载。
*/
private static class SingletonContainer {
private static Singleton instance = new Singleton();
}
public static Singleton getInstance2() {
return SingletonContainer.instance;
}
public void doSomething()
{
}
}