我是靠谱客的博主 欣喜飞机,最近开发中收集的这篇文章主要介绍java设计模式-创建型模式-单例模式单例模式回到主目录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

单例模式

单例模式,保持对象的唯一性。
私有构造方法,提供一个返回具体对象的方法。

  • 饿汉式单例模式

对象在使用前已经被创建好,所以无论怎样调用,返回的都是同一个对象,所以是线程安全的

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设计模式-创建型模式-单例模式单例模式回到主目录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部