java单例模式,多线程下实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java单例模式,多线程下实现相关的知识,希望对你有一定的参考价值。

单例模式

必备条件:

1:private的构造方法。

2:private static 对象保存该类实例。

3:static方法返回该类实例。

(一)饿汉模式

/**
 * 单例模式
 * 1:线程安全实现
 * 2:浪费内存
 * @author 祥少
 *
 */
public class SingletonTest {

  //final关键字,导致一旦被初始化,一直占用该段内存(即使你不使用)
    public static final SingletonTest singletonTest = new SingletonTest();;

    private SingletonTest() {

    }

    public static SingletonTest getSingleton() {

        return singletonTest;
    }

    public static void main(String[] args) {
        long current=System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingletonTest.getSingleton().hashCode());
                }
            }).start();
        }
        if (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println("执行结束耗时:"+(System.currentTimeMillis()-current));
    }
}

 

(二)饱汉模式
/**
 * 单例模式
 * 1:线程不安全
 * getSingleton()函数线程不安全
 *@author 祥少
 */
public class SingletonTest {
    public static SingletonTest singletonTest = null;

    private SingletonTest() {

    }

    public static SingletonTest getSingleton() {
        if (singletonTest == null) {
            singletonTest = new SingletonTest();
        }
        return singletonTest;
    }

    public static void main(String[] args) {
        long current = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingletonTest.getSingleton().hashCode());
                }
            }).start();
        }

        // 判断线程是否结束
        if (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println("执行结束耗时:" + (System.currentTimeMillis() - current));
    }
}

 

线程安全改进方法:

 

(方法1)

    public static synchronized SingletonTest getSingleton() {
        if (singletonTest == null) {
            singletonTest = new SingletonTest();
        }
        return singletonTest;
    }

优点:synchronized关键字实现线程安全。
缺点:整个函数加锁效率略低(几乎等于单线程)。

 

(方法2:双加锁)   

    public static volatile SingletonTest singletonTest = null;

    public static SingletonTest getSingleton() {
        if (singletonTest == null) {
            synchronized (SingletonTest.class) {
                if (singletonTest == null) {
                    singletonTest = new SingletonTest();
                }
            }            
        }
        return singletonTest;
    }


最佳实现:效率高,线程安全,volatile 保证操作原子性,只有%1的线程需要进入锁代码。

 


































































































以上是关于java单例模式,多线程下实现的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程(单例模式堵塞队列定时器)

单例模式在多线程下的多种实现模式

多线程下的单例模式详解

java-多线程下的单例模式

Java 多线程下的单例模式

多线程下的单例模式详解