commit bf4fe52eb3855e86a7490b8031a5e839063e5b37 Author: terry <724796052@qq.com> Date: Sun Jun 26 09:13:47 2022 +0800 单例模式 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/src/singleton/Singleton1.java b/src/singleton/Singleton1.java new file mode 100644 index 0000000..523c5ba --- /dev/null +++ b/src/singleton/Singleton1.java @@ -0,0 +1,22 @@ +package singleton; + +/* + * 饿汉式 + * 类加载到内存后,就实例化一个单例,JVM保证线程安全 + * 缺点: 不管用到与否,类加载时就完成实例化 + * */ +public class Singleton1 { + private static final Singleton1 INSTANCE = new Singleton1(); + + private Singleton1() { + } + + public static Singleton1 getInstance() { + return INSTANCE; + } + + public static void main(String[] args) { + Singleton1 singleton = Singleton1.getInstance(); + System.out.println(singleton); + } +} diff --git a/src/singleton/Singleton2.java b/src/singleton/Singleton2.java new file mode 100644 index 0000000..190826c --- /dev/null +++ b/src/singleton/Singleton2.java @@ -0,0 +1,23 @@ +package singleton; + +/* + * 同1 + * */ +public class Singleton2 { + private static final Singleton2 INSTANCE; + static { + INSTANCE = new Singleton2(); + } + + private Singleton2() { + } + + public static Singleton2 getInstance() { + return INSTANCE; + } + + public static void main(String[] args) { + Singleton2 singleton = Singleton2.getInstance(); + System.out.println(singleton); + } +} diff --git a/src/singleton/Singleton3.java b/src/singleton/Singleton3.java new file mode 100644 index 0000000..051c77b --- /dev/null +++ b/src/singleton/Singleton3.java @@ -0,0 +1,27 @@ +package singleton; + +/* + * 懒汉式 lazy loading + * 虽然达到了按需初始化的目的, 但却带来了线程不安全问题 + * */ +public class Singleton3 { + private static Singleton3 INSTANCE; + + private Singleton3() { + } + + public static Singleton3 getInstance() { + if(INSTANCE == null){ + INSTANCE = new Singleton3(); + } + return INSTANCE; + } + + public static void main(String[] args) { + Singleton3 singleton = Singleton3.getInstance(); + //多线程 访问可能造成new出多个实例 第一个线程判读为null的时候还没new完对象 第二个线程进来,也new了一个对象 + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(singleton.hashCode())).start(); + } + } +} diff --git a/src/singleton/Singleton4.java b/src/singleton/Singleton4.java new file mode 100644 index 0000000..f048aa1 --- /dev/null +++ b/src/singleton/Singleton4.java @@ -0,0 +1,27 @@ +package singleton; + +/* + * 懒汉式 lazy loading + * 虽然达到了按需初始化的目的, 加锁 效率降低 + * */ +public class Singleton4 { + private static Singleton4 INSTANCE; + + private Singleton4() { + } + + public static synchronized Singleton4 getInstance() { + if(INSTANCE == null){ + INSTANCE = new Singleton4(); + } + return INSTANCE; + } + + public static void main(String[] args) { + Singleton4 singleton = Singleton4.getInstance(); + //多线程 访问可能造成new出多个实例 第一个线程判读为null的时候还没new完对象 第二个线程进来,也new了一个对象 + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(singleton.hashCode())).start(); + } + } +} diff --git a/src/singleton/Singleton5.java b/src/singleton/Singleton5.java new file mode 100644 index 0000000..d2e1acd --- /dev/null +++ b/src/singleton/Singleton5.java @@ -0,0 +1,29 @@ +package singleton; + +/* + * 懒汉式 lazy loading + * 虽然达到了按需初始化的目的, 加锁, 加在代码块上 + * */ +public class Singleton5 { + private static Singleton5 INSTANCE; + + private Singleton5() { + } + + //线程不安全,同3类似 + public static Singleton5 getInstance() { + if(INSTANCE == null){ + synchronized (Singleton5.class){ + INSTANCE = new Singleton5(); + } + } + return INSTANCE; + } + + public static void main(String[] args) { + Singleton5 singleton = Singleton5.getInstance(); + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(singleton.hashCode())).start(); + } + } +} diff --git a/src/singleton/Singleton6.java b/src/singleton/Singleton6.java new file mode 100644 index 0000000..c864a53 --- /dev/null +++ b/src/singleton/Singleton6.java @@ -0,0 +1,29 @@ +package singleton; + +/* + * 懒汉式 lazy loading + * 虽然达到了按需初始化的目的, 同步代码块 + * */ +public class Singleton6 { + private static Singleton6 INSTANCE; + + private Singleton6() { + } + + public static synchronized Singleton6 getInstance() { + synchronized (Singleton6.class){ + //双重检查 + if(INSTANCE == null) { + INSTANCE = new Singleton6(); + } + } + return INSTANCE; + } + + public static void main(String[] args) { + Singleton6 singleton = Singleton6.getInstance(); + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(singleton.hashCode())).start(); + } + } +} diff --git a/src/singleton/Singleton7.java b/src/singleton/Singleton7.java new file mode 100644 index 0000000..61ce90a --- /dev/null +++ b/src/singleton/Singleton7.java @@ -0,0 +1,25 @@ +package singleton; + +/* + * 静态内部类方式 jvm保证单例 + * 加载外部类时不会加载内部类,这样实现了懒加载 + * */ +public class Singleton7 { + + private Singleton7() { + } + + private static class SingletonHolder{ + private static Singleton7 INSTANCE = new Singleton7(); + } + public static synchronized Singleton7 getInstance() { + return SingletonHolder.INSTANCE; + } + + public static void main(String[] args) { + Singleton7 singleton = Singleton7.getInstance(); + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(singleton.hashCode())).start(); + } + } +} diff --git a/src/singleton/Singleton8.java b/src/singleton/Singleton8.java new file mode 100644 index 0000000..7dbdbf8 --- /dev/null +++ b/src/singleton/Singleton8.java @@ -0,0 +1,15 @@ +package singleton; + +/* + * 枚举方式, 不仅解决了线程同步,也防止了反序列化 + * */ +public enum Singleton8 { + + INSTANCE; + + public static void main(String[] args) { + for (int i=0; i< 100; i++){ + new Thread(() -> System.out.println(Singleton8.INSTANCE.hashCode())).start(); + } + } +}