java单例模式

判断是否存在

/** 
 * 懒汉式 
 */
public class LazySingleInstance {  
    
    // 私有构造方法  
    private LazySingleInstance(){};  
        
    // 私有的类对象  
    private static LazySingleInstance instance = null;  
        
    // 缺点:  
    // 1 每次都需要去判断instance 是否为空  
    // 2 调用时才去new对象,响应比较慢  
    // 3 多线程时,线程不安全,多线程同时获取该对象,线程不安全,可能会产生多个对象出来  
    public static LazySingleInstance getInstance() throws InterruptedException {  
        // 每次都需要判断instance是否为空,浪费资源  
        if (null == instance) {  
            Thread.sleep(1000);  
            instance = new LazySingleInstance();  
        }  
            
        return instance;  
    }  
}

考虑线程

/**
 * 懒汉式线程安全方法一
 */ 

public class ThreadSafeSingleInstance {  
   
    // 私有的静态实例  
    private static ThreadSafeSingleInstance instance;  
       
    // 私有的构造方法  
    private ThreadSafeSingleInstance(){};  
       
    /** 
     * 懒汉式线程安全方法 
     * 同步锁保护 
     * 缺点: 
     * 性能低下,且同时每次均需检查实例是否存在 
     * @return 
     * @throws InterruptedException  
     */ 
    public synchronized static ThreadSafeSingleInstance getInstance() throws InterruptedException {  
        if (instance == null) {  
            Thread.sleep(1000);  
            instance = new ThreadSafeSingleInstance();  
        }  
           
        return instance;  
    }  
       
}
/** 
 * 懒汉式线程安全方法二 
 */ 
public class ThreadSafeSingleInstance {  
   
    // 私有的静态实例  
    private static ThreadSafeSingleInstance instance;  
       
    // 私有的构造方法  
    private ThreadSafeSingleInstance(){};  
       
    /** 
     * 同步块保护加二次判断 
     * 解决问题 
     */ 
    public static ThreadSafeSingleInstance getInstance() throws InterruptedException {  
        if (instance == null) {  
            // 进方法后进行实例判断,若实例为空,进入同步块  
            // 多线程时,多个线程会同时进入到同步块外面等待  
            // 此时,一个线程拿到ThreadSafeSingleInstance.class 后,其他线程在synchronized块外面等待  
            // 待锁释放时,一个等待的线程拿到锁,同时再次检查实例是否为空  
            // 并决定是否要创建实例  
            synchronized (String.class) {//ThreadSafeSingleInstance.class) {  
                Thread.sleep(1000);  
                if (instance == null) {  
                    instance = new ThreadSafeSingleInstance();  
                }  
            }  
        }  
           
        return instance;  
    }  
       
}

 

每次都去new

 

/** 
 * 饿汉式 
 */ 
public class HungrySingleInstance {  
   
    // 私有的构造方法  
    private HungrySingleInstance(){};  
       
    // 静态类变量,初始化类时变创建对象  
    private static HungrySingleInstance instance = new HungrySingleInstance();  
       
    // 或采用静态块形式初始化instance  
    static {  
        instance = new HungrySingleInstance();  
    }  
       
    /** 
     * 获取实例方法 
     * 优点: 
     * 线程安全,且不存在懒汉式的二次判断问题 
     * 缺点: 
     * 初始化即new 实例对象出来,违背资源利用习惯(即不管用不用都初始化实例出来) 
     * @return 
     */ 
    public static HungrySingleInstance getInstance() {  
        return instance;  
    }  
}

 

 

测试类

 

public class SingleInstanceTest implements Runnable{  
   
    HungrySingleInstance hungrySingleInstance = null;  
       
    LazySingleInstance lazySingleInstance = null;  
       
    ThreadSafeSingleInstance threadSafeSingleInstance = null;  
       
//  @Override  
//  public void run() {  
//      hungrySingleInstance = HungrySingleInstance.getInstance();  
//      System.out.println("hungrySingleInstance.hashCode() " + hungrySingleInstance.hashCode());  
//        
//  }  
       
//  @Override  
//  public void run() {  
//      try {  
//          lazySingleInstance = LazySingleInstance.getInstance();  
//      } catch (InterruptedException e) {  
//          e.printStackTrace();  
//      }  
//      System.out.println("lazySingleInstance.hashCode() " + lazySingleInstance.hashCode());  
//  }  
       
    @Override  
    public void run() {  
        try {  
            threadSafeSingleInstance = ThreadSafeSingleInstance.getInstance();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("threadSafeSingleInstance() " + threadSafeSingleInstance.hashCode());  
    }  
   
    public static void main(String args[]) throws InterruptedException{  
        SingleInstanceTest singleInstanceTest = new SingleInstanceTest();  
           
        for (int i=0; i< 100; i++) {  
            Thread t = new Thread(singleInstanceTest, String.valueOf(i));  
            t.start();  
        }  
    }  
}

 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

返回顶部