波神

导航

java常用设计模式一:单例模式

 1、饿汉式

package singleton.demo;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Singleton {
    //在调用getInstance方法前,实例已经创建好
    private static Singleton instance = new Singleton();

    //私有构造,防止被实例化
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

2、懒汉式

package singleton.demo;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Singleton {
    //初始设置为null,需要时才被加载,延迟加载
    private static Singleton instance = null;

    //私有构造,防止被实例化
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

 

以上两种模式:只适合在单线程环境使用,多线程环境容易出现不同步的情况。在多线程模式下,可能产生问题。比如下面的实例

package singleton.demo;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Singleton {
    //初始设置为null,需要时才被加载,延迟加载
    private static Singleton instance = null;

    //私有构造,防止被实例化
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new Singleton();
        }
        return instance;
    }
}
package singleton.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Test {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i=0;i<5;i++){
            executorService.submit(new Runnable() {
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            });
        }
        executorService.shutdown();

    }
}

执行结果:

1369340138
1555013046
285003072
270952636
84064941

 之所以出现不同步,是因为,当多个线程执行 getInstance() 的时候,都发现instance是null,所以每个线程各自创建了一个instance

 3、使用static块实现线程安全的单例模式

注意:以下try-catch不是模式需要的代码,这里只是为了测试多线程环境才加上的

package singleton.demo;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Singleton {
    //初始设置为null,需要时才被加载,延迟加载
    private static Singleton instance = null;

    //私有构造,防止被实例化
    private Singleton() {}

    static {
        instance = new Singleton();
    }

    public static Singleton getInstance() {
        if (instance == null) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new Singleton();
        }
        return instance;
    }
}
package singleton.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Administrator
 * @date 2019/01/07
 */
public class Test {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i=0;i<5;i++){
            executorService.submit(new Runnable() {
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            });
        }
        executorService.shutdown();

    }
}
2050945573
2050945573
2050945573
2050945573
2050945573

 

posted on 2018-05-23 13:38  波神  阅读(167)  评论(0编辑  收藏  举报