本文共 4534 字,大约阅读时间需要 15 分钟。
只能生成一个实例的类是实现了Singleton(单例)模式的类。以下为C#实现单例模式的方式
方式一只使用于单线程环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // 把构造函数设为私有函数以禁止他人创建实例 // 定义一个静态的实例,在需要的时候创建该实例 // 在Singleton的静态属性Instance中,只有在instance为null的时候才创建一个实例以避免重复创建 // 把构造函数定义为私有函数 public final class Singleton1 { private Singleton1() { } private static Singleton1 _instance = null ; public static Singleton1 getInstance() { if (_instance == null ) _instance = new Singleton1(); return _instance; } public static void main(String[] args) { Singleton1 s1 = Singleton1.getInstance(); Singleton1 s2 = Singleton1.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |
方式二 加同步锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public final class Singleton2 { private Singleton2(){} static Lock lock = new ReentrantLock(); private static Singleton2 _instance = null ; public static Singleton2 getInstance(){ lock.lock(); try { if (_instance == null ) _instance = new Singleton2(); } finally { lock.unlock(); } return _instance; } public static void main(String[] args) { Singleton2 s1 = Singleton2.getInstance(); Singleton2 s2 = Singleton2.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |
可行的解法 加同步锁前后两次判断实例是否已存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public final class Singleton3 { private Singleton3(){} static Lock lock = new ReentrantLock(); private static Singleton3 _instance = null ; public static Singleton3 getInstance(){ if (_instance == null ){ lock.lock(); try { if (_instance == null ) _instance = new Singleton3(); } finally { lock.unlock(); } } return _instance; } public static void main(String[] args) { Singleton3 s1 = Singleton3.getInstance(); Singleton3 s2 = Singleton3.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |
推荐的解法一利用静态构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public final class Singleton4 { private Singleton4(){} private static Singleton4 _instance = new Singleton4(); public static Singleton4 getInstance() { return _instance; } public static void main(String[] args) { Singleton4 s1 = Singleton4.getInstance(); Singleton4 s2 = Singleton4.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |
推荐的解法二 实现按需创建实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class Singleton5 { private Singleton5(){} public static Singleton5 getInstance(){ return Nested.instance; } private static class Nested{ private Nested(){} public static final Singleton5 instance = new Singleton5(); } public static void main(String[] args) { Singleton5 s1 = Singleton5.getInstance(); Singleton5 s2 = Singleton5.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |
扩展
定义一个表示总统的类型President可以从该类型继承出FrenchPresident和AmericanPresident等类型。这些派生类型都只能产生一个实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | public class President { private String _name; public President(){} public String getName(){ return _name; } public void setName(String name){ _name = name; } public static void main(String[] args) { } } public class FrenchPresident extends President{ private FrenchPresident(){} public static FrenchPresident getInstance() { return Nested.instance; } private static class Nested{ private Nested(){} public static final FrenchPresident instance = new FrenchPresident(); } public static void main(String[] args) { FrenchPresident s1 = FrenchPresident.getInstance(); FrenchPresident s2 = FrenchPresident.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } public class AmericanPresident { private AmericanPresident() { } public static AmericanPresident getInstance() { return Nested.instance; } private static class Nested { private Nested() { } public static final AmericanPresident instance = new AmericanPresident(); } public static void main(String[] args) { AmericanPresident s1 = AmericanPresident.getInstance(); AmericanPresident s2 = AmericanPresident.getInstance(); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } } |