diff --git a/src/com/msb/singleton/Singleton01.java b/src/com/msb/singleton/Singleton01.java new file mode 100644 index 0000000..4ff0c8c --- /dev/null +++ b/src/com/msb/singleton/Singleton01.java @@ -0,0 +1,30 @@ +package com.msb.singleton; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 饿汉式 + * 类加载到内存后,就实例化一个单例,JVM保证线程安全 + * 简单实用,推荐使用! + * 唯一缺点:不管用到与否,类加载是就完成了实例化 + * (话说你不用的,你装载它干啥) + * @Version: 1.0 + */ +public class Singleton01 { + + private static final Singleton01 INSTANCE = new Singleton01(); + + private Singleton01() {} + + public static Singleton01 getInstance() { + return INSTANCE; + } + + public static void main(String[] args) { + Singleton01 singleton1 = Singleton01.getInstance(); + Singleton01 singleton2 = Singleton01.getInstance(); + System.out.println(singleton1 == singleton2); + } + +} diff --git a/src/com/msb/singleton/Singleton02.java b/src/com/msb/singleton/Singleton02.java new file mode 100644 index 0000000..711ed9e --- /dev/null +++ b/src/com/msb/singleton/Singleton02.java @@ -0,0 +1,29 @@ +package com.msb.singleton; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: 跟01一样,只是使用了静态语句快 + * @Version: 1.0 + */ +public class Singleton02 { + + private static final Singleton02 INSTANCE; + + static { + INSTANCE = new Singleton02(); + } + + private Singleton02() {} + + public static Singleton02 getInstance() { + return INSTANCE; + } + + public static void main(String[] args) { + Singleton02 singleton1 = Singleton02.getInstance(); + Singleton02 singleton2 = Singleton02.getInstance(); + System.out.println(singleton1 == singleton2); + } + +} diff --git a/src/com/msb/singleton/Singleton03.java b/src/com/msb/singleton/Singleton03.java new file mode 100644 index 0000000..4272f05 --- /dev/null +++ b/src/com/msb/singleton/Singleton03.java @@ -0,0 +1,39 @@ +package com.msb.singleton; + +import java.util.Objects; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 懒汉式: + * 虽然达到了按需初始化的目的,但却带来了线程不安全的问题 + * @Version: 1.0 + */ +public class Singleton03 { + + private static Singleton03 INSTANCE; + + private Singleton03() {} + + public static Singleton03 getInstance() { + if(Objects.isNull(INSTANCE)) { + try { //这里是为了测试线程 + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + INSTANCE = new Singleton03(); + } + return INSTANCE; + } + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton03.getInstance().hashCode()); + }).start(); + } + } + +} diff --git a/src/com/msb/singleton/Singleton04.java b/src/com/msb/singleton/Singleton04.java new file mode 100644 index 0000000..524466b --- /dev/null +++ b/src/com/msb/singleton/Singleton04.java @@ -0,0 +1,40 @@ +package com.msb.singleton; + +import java.util.Objects; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 懒汉式: + * 虽然达到了按需初始化的目的,但却带来了线程不安全的问题 + * 可以通过synchronized解决,但也带来了效率下降 + * @Version: 1.0 + */ +public class Singleton04 { + + private static Singleton04 INSTANCE; + + private Singleton04() {} + + public static synchronized Singleton04 getInstance() { + if(Objects.isNull(INSTANCE)) { + try { //这里是为了测试线程 + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + INSTANCE = new Singleton04(); + } + return INSTANCE; + } + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton04.getInstance().hashCode()); + }).start(); + } + } + +} diff --git a/src/com/msb/singleton/Singleton05.java b/src/com/msb/singleton/Singleton05.java new file mode 100644 index 0000000..4008005 --- /dev/null +++ b/src/com/msb/singleton/Singleton05.java @@ -0,0 +1,43 @@ +package com.msb.singleton; + +import java.util.Objects; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 懒汉式: + * 虽然达到了按需初始化的目的,但却带来了线程不安全的问题 + * 可以通过synchronized解决,但也带来了效率下降 + * @Version: 1.0 + */ +public class Singleton05 { + + private static Singleton05 INSTANCE; + + private Singleton05() {} + + public static Singleton05 getInstance() { + if(Objects.isNull(INSTANCE)) { + //试图减少同步代码块的方式来提高效率,然而不可行,仍然会有线程不安全问题 + synchronized (Singleton05.class) { + try { //这里是为了测试线程 + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + INSTANCE = new Singleton05(); + } + } + return INSTANCE; + } + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton05.getInstance().hashCode()); + }).start(); + } + } + +} diff --git a/src/com/msb/singleton/Singleton06.java b/src/com/msb/singleton/Singleton06.java new file mode 100644 index 0000000..878ef74 --- /dev/null +++ b/src/com/msb/singleton/Singleton06.java @@ -0,0 +1,45 @@ +package com.msb.singleton; + +import java.util.Objects; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 懒汉式: + * 虽然达到了按需初始化的目的,但却带来了线程不安全的问题 + * 可以通过synchronized解决,但也带来了效率下降 + * @Version: 1.0 + */ +public class Singleton06 { + + private static Singleton06 INSTANCE; + + private Singleton06() {} + + public static Singleton06 getInstance() { + if(Objects.isNull(INSTANCE)) { + //试图减少同步代码块的方式来提高效率,然而不可行,仍然会有线程不安全问题 + synchronized (Singleton06.class) { + if(Objects.isNull(INSTANCE)) { + try { //这里是为了测试线程 + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + INSTANCE = new Singleton06(); + } + } + } + return INSTANCE; + } + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton06.getInstance().hashCode()); + }).start(); + } + } + +} diff --git a/src/com/msb/singleton/Singleton07.java b/src/com/msb/singleton/Singleton07.java new file mode 100644 index 0000000..95efc70 --- /dev/null +++ b/src/com/msb/singleton/Singleton07.java @@ -0,0 +1,34 @@ +package com.msb.singleton; + +import java.util.Objects; + +/** + * @Author bingor + * @Date 2022-10-06 10:25 + * @Description: + * 静态内部类方式 + * JVM保证单例 + * 加载外部类时不会加载内部类,这样可以实现懒加载 + * @Version: 1.0 + */ +public class Singleton07 { + + private Singleton07() {} + + private static class Singleton07Holder { + private static final Singleton07 INSTANCE = new Singleton07(); + } + + public static Singleton07 getInstance() { + return Singleton07Holder.INSTANCE; + } + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton07.getInstance().hashCode()); + }).start(); + } + } + +} diff --git a/src/com/msb/singleton/Singleton08.java b/src/com/msb/singleton/Singleton08.java new file mode 100644 index 0000000..ecf0ea4 --- /dev/null +++ b/src/com/msb/singleton/Singleton08.java @@ -0,0 +1,19 @@ +package com.msb.singleton; + +/** + * @Author bingor + * @Date 2022-10-06 11:20 + * @Description: 不仅可以解决线程同步,还可以防止反序列化 + * @Version: 1.0 + */ +public enum Singleton08 { + INSTANCE; + + public static void main(String[] args) { + for (int i=0; i<100; i++) { + new Thread(() -> { //同样的哈希码,可能是不同的对象。但不同的对象,有不同的哈希码 + System.out.println(Singleton08.INSTANCE.hashCode()); + }).start(); + } + } +}