概述
单例模式
单例模式,保持对象的唯一性。
私有构造方法,提供一个返回具体对象的方法。
-
饿汉式单例模式
对象在使用前已经被创建好,所以无论怎样调用,返回的都是同一个对象,所以是线程安全的
public class EagerSingleton {
/**
* 饿汉式直接初始化
*/
private static EagerSingleton instance = new EagerSingleton();
public static EagerSingleton getInstance() {
return instance;
}
private EagerSingleton() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> System.out.println(EagerSingleton.getInstance().hashCode())).start();
}
}
}
结果
355159803
355159803
355159803
355159803
355159803
355159803
355159803
355159803
355159803
355159803
-
懒汉式单例模式
什么时候使用什么时候创建对象,多线程下调用无法保证对象唯一
public class LazySingleton {
public static LazySingleton getInstance() {
try {
if (null == instance) {
Thread.sleep(1000);
instance = new LazySingleton();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
private static LazySingleton instance = null;
private LazySingleton() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> System.out.println(LazySingleton.getInstance().hashCode())).start();
}
}
}
结果
1184554318
1750416013
1294123621
1516133987
1184554318
1831557028
640934955
21895028
2034349848
1736289754
-
懒汉式单例模式-用synchronized关键字修饰方法
将返回对象的方法加synchronized修饰成同步方法,这样可以保证对象的唯一性,但是整个方法都加了同步,所以效率会降低。
public class LazySingletonSynchronizedMethod {
public synchronized static LazySingletonSynchronizedMethod getInstance() {
if (null == instance) {
try {
Thread.sleep(1000);
instance = new LazySingletonSynchronizedMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return instance;
}
private static LazySingletonSynchronizedMethod instance = null;
private LazySingletonSynchronizedMethod() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> System.out.println(LazySingletonSynchronizedMethod.getInstance().hashCode())).start();
}
}
}
结果
1184554318
1184554318
1184554318
1184554318
1184554318
1184554318
1184554318
1184554318
1184554318
1184554318
-
懒汉式单例模式-用synchronized关键字修饰创建对象的代码块
synchronized修饰方法效率降低,改为修饰创建对象的代码块,比直接修饰方法效率会好一些,但是效率同样也会降低
public class LazySingletonSynchronizedBlock {
public static LazySingletonSynchronizedBlock getInstance() {
try {
synchronized (LazySingletonSynchronizedBlock.class) {
if (null == instance) {
Thread.sleep(1000);
instance = new LazySingletonSynchronizedBlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
private static LazySingletonSynchronizedBlock instance = null;
private LazySingletonSynchronizedBlock() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> System.out.println(LazySingletonSynchronizedBlock.getInstance().hashCode())).start();
}
}
}
结果
375869755
375869755
375869755
375869755
375869755
375869755
375869755
375869755
375869755
375869755
-
懒汉式单例模式-双重检查锁机制
用synchronized关键字修饰代码块,同时使用volatile来保证可见性
public class LazySingletonDoubleCheckLock {
public static LazySingletonDoubleCheckLock getInstance() {
try {
if (null == instance) {
Thread.sleep(1000);
synchronized (LazySingletonDoubleCheckLock.class) {
if (null == instance) {
instance = new LazySingletonDoubleCheckLock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
private volatile static LazySingletonDoubleCheckLock instance = null;
private LazySingletonDoubleCheckLock() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> System.out.println(LazySingletonDoubleCheckLock.getInstance().hashCode())).start();
}
}
}
结果
21895028
21895028
21895028
21895028
21895028
21895028
21895028
21895028
21895028
21895028
-
静态内部类实现单例模式
public class StaticInnerClassSingleton {
public static StaticInnerClassSingleton getInstance() {
return StaticInnerClassSingletonHandler.instance;
}
private StaticInnerClassSingleton() {
}
private static class StaticInnerClassSingletonHandler {
private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(StaticInnerClassSingleton.getInstance().hashCode());
}).start();
}
}
}
-
静态代码块实现单例模式
public class StaticBlockSingleton {
private static StaticBlockSingleton instance = null;
static {
instance = new StaticBlockSingleton();
}
private StaticBlockSingleton() {
}
public static StaticBlockSingleton getInstance() {
return instance;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(StaticBlockSingleton.getInstance().hashCode());
}).start();
}
}
}
-
枚举类实现单例模式
ublic enum SingletonEnum {
INSTANCE;
private Singleton instance;
SingletonEnum() {
System.out.println("只会调用一次");
instance = new Singleton();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(SingletonEnum.INSTANCE.hashCode());
}).start();
}
}
}
class Singleton{
}
总结
单例模式的实现大体分为两类
- 调用前初始化对象,调用方法时返回这个初始化好的对象,线程安全
- 调用时初始化对象,线程不安全,所以需要增加代码来保证线程安全
回到主目录
最后
以上就是欣喜飞机为你收集整理的java设计模式-创建型模式-单例模式单例模式回到主目录的全部内容,希望文章能够帮你解决java设计模式-创建型模式-单例模式单例模式回到主目录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复