常见单例模式

package test.singleton;

import java.util.ArrayList;
import java.util.List;

/**
 * 饿汉式单例--线程安全
 * 由于使用static关键字进行了修饰,只能获取到一个对象,从而达到了单例,并且在Singleton类初始化的时候就创建了对象,加载到了内存。
 * 问题:在没有使用这个对象的情况下就加载到内存是一种很大的浪费
 */
public class Singletion1 {
    private static final Singletion1 instance = new Singletion1();

    public static Singletion1 getInstance() {
        return instance;
    }

    /**
     * 构造私有化
     */
    private Singletion1() {
    }

    static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Singletion1.getInstance().hashCode());
        }
    }

    public static void main(String[] args) {
        List<MyThread> list = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            MyThread thread = new MyThread();
            list.add(thread);
        }
        System.out.println("##########开始执行线程###############");
        long startTime = System.currentTimeMillis();
        for (MyThread thread : list) {
            thread.start();
        }
        System.out.println("线程大小:" +list.size() + ",执行时间totalTime="+(System.currentTimeMillis()-startTime)/1000 +"s" );
    }
}

懒汉式单例

针对这种情况,有一种新的思想提出——延迟加载,也就是所谓的懒汉式。
*
* 懒汉式(存在线程安全问题):
public class Singleton2 {
    private static Singleton2 instance =null;

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

    /**
     * 构造私有化
     */
    private Singleton2() {
    }

    static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Singleton2.getInstance().hashCode());
        }
    }

    public static void main(String[] args) {
//        List<Singletion2.MyThread> list = new ArrayList<>(10);
        List<Singleton2.MyThread> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Singleton2.MyThread thread = new Singleton2.MyThread();
            list.add(thread);
        }
        System.out.println("##########开始执行线程###############");
        long startTime = System.currentTimeMillis();
        for (Singleton2.MyThread thread : list) {
            thread.start();
        }
        System.out.println("线程大小:" +list.size() + ",执行时间totalTime="+(System.currentTimeMillis()-startTime)/1000 +"s" );
    }
}

内部类单例

/**
 * 这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,
 * JLS(Java Language Sepcification)会保证这个类的线程安全
 */
public class StaticSingleton {
    private StaticSingleton() {
    }

    private static class SingletonHolder {
        public final static StaticSingleton instance = new StaticSingleton();
    }

    public static StaticSingleton getInstance() {
        return SingletonHolder.instance;
    }

    static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Singletion1.getInstance().hashCode());
        }
    }

    public static void main(String[] args) {
        List<StaticSingleton.MyThread> list = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            StaticSingleton.MyThread thread = new StaticSingleton.MyThread();
            list.add(thread);
        }
        System.out.println("##########开始执行线程###############");
        long startTime = System.currentTimeMillis();
        for (StaticSingleton.MyThread thread : list) {
            thread.start();
        }
        System.out.println("线程大小:" +list.size() + ",执行时间totalTime="+(System.currentTimeMillis()-startTime)/1000 +"s" );
    }
}

猜你喜欢

转载自my.oschina.net/huyuBlog/blog/1813764