单例模式
必备条件:
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的线程需要进入锁代码。