数学建模社区-数学中国
标题: 浅谈单例模式的实现方式 [打印本页]
作者: 杨利霞 时间: 2020-3-30 17:20
标题: 浅谈单例模式的实现方式
浅谈单例模式的实现方式 {# k* x2 g n7 W; R
单例模式(来自菜鸟教程)2 k$ p, E' [4 j/ x+ t0 w% S
+ ~9 G; I6 a( |7 ^单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。- [5 U. Q2 R4 E8 C
单例模式的要求
* d R! s6 v) u9 f% i" V
! Y4 @; b7 q4 g% V R构造方法必须私有化(确保只有自己能创建)
% O; }6 I4 \3 ~( `( g7 F% X# B1 b以静态方法返回实例(外界不能通过new来获取到对象)
9 Z4 j9 \ J7 t/ R确保对象实例只有一个(只对类进行一次实例化,以后都直接获取第一次实例化的对象)
/ _6 w- f/ @) |. P# Y+ F! t' t: n单例模式的实现
2 Q6 s" X4 \7 }) \& `/ U9 h+ w9 _
1、懒汉式(线程不安全)
, e& n) l- K! f7 J: Q- L9 d$ P6 ^# d# W4 T6 j8 ~4 w4 d
描述:这种方式是最基本的实现方式,但是不支持多线程。因为没有加锁,在多线程不能正常工作' {; g' n7 J% o# `4 U" |
//懒汉式(线程不安全) z# k! ^5 n8 M' Z& Z
public class Singleton {
2 D0 T5 \& w& z+ s/ J7 U1 z private static Singleton instance; 9 y' D6 |% a6 F' t
0 k' c+ N! I I5 T& b private Singleton (){} % s0 B0 e- w: t9 Q v' l6 I e
$ ~# _9 |* N6 i7 _! {3 \# ` public static Singleton getInstance() { ! M* n" ^- D, C$ ~$ P$ s. X
if (instance == null) {
! l. z- x" `+ U instance = new Singleton();
/ w4 i' X4 {+ _6 \8 }. g }
" i. ~. e! s2 _- i; ~" Q1 I return instance;
( I- a$ g% s, h% e3 I. Q' S! h3 u } 3 p) r3 @+ X( ?" N* h$ @
}/ {9 c- \ V' O' t2 z W
2、懒汉式(线程安全)
描述:能够在多线程下正常工作,但是,效率极低
//懒汉式(线程安全)* j5 _0 ?) F* R5 f
public class Singleton {
1 ?8 y/ @0 w( z- q+ d private static Singleton instance; B$ t; l6 \ a& b
/ V3 \) _7 q6 U# I9 Q1 ?& q0 `
private Singleton (){}
" D3 t) Q) q, E$ V9 ^# n- O
6 B" ~# S! K/ c8 S( Q1 a public static synchronized Singleton getInstance() {
+ R1 U6 i6 }5 m$ g. w if (instance == null) { q" K2 K! @9 C! X. T
instance = new Singleton(); 5 Y O# b" I4 w2 o8 N
}
2 n5 b6 n& q6 A" B- \# o return instance;
% {! @% E% k2 H( k1 G }
+ H0 V5 E6 e( s8 Y1 Q4 f" r}
9 P) d/ W0 _' i/ h! P' i% C0 U7 Q& c' t$ h, i, o# w
3、双重校验锁(DCL,即double-checked locking)(线程安全)
描述:对懒汉式(线程安全)的优化,采用双锁的机制,安全且在多线程情况下能保持高性能
6 G8 e. B. b+ b% l0 n% P" }//双重校验锁
1 L( ^, k+ z% tpublic class Singleton {- W' K! ?) d# ?. u5 ?
private volatile static Singleton instance;/ B$ T+ m' o* Y& R* ?- }+ M
/ k% R# [) _1 j2 g private Singleton() {
$ L' J ]; e9 P {2 {; \& C2 ~% u/ W5 [3 T+ S, Q/ n
}
9 R* A; T9 I8 j8 X2 e
1 F& @' X2 r% K, h% D public static Singleton getInstance() {5 w s* u, H: R; |
if (instance == null) {. P5 r, h6 X% z" s5 F
synchronized (Singleton.class) {! i' E$ g& X' B3 G3 q
if (instance == null) {
( ]2 Q w! T* a4 u instance = new Singleton();+ f" m2 v B2 @) @* ?! d) A
}
6 O7 K5 }) g% J+ q; @ }7 u" H9 c- N: t
}
, g; z2 u/ v3 p* z return instance;( F- e& R6 [* O0 J0 N% {" w; k
}
/ _6 ^) m7 Z3 X8 C}1 E+ v( `" f8 I/ b
; Y1 z! H5 p9 \# T) d6 S& \- K# v; q7 V5 [
4、饿汉式(线程安全)
描述:这种方式比较常用,但容易产生垃圾对象
$ o: v& q" \) Z' p* o" l. r//饿汉式
, S3 }# }7 c6 T" wpublic class Singleton {/ T- K& H/ Q, `7 C
private static Singleton instance = new Singleton();# i, g/ A; l5 ^0 t% f& C
7 s% S) a* z* v7 m2 `2 v private Singleton() {
! u9 G( d* L* g5 \$ J1 X: X% k3 Y( d! i. k, {
}
7 V' I4 h; a) c7 H2 o* G+ E1 V7 I+ K; P$ r8 A. c5 ~+ y
public static Singleton getInstance() {
2 _3 F9 J" O0 I return instance;8 x5 @2 n9 `7 r" ?/ j' O* l
}
7 b/ X, i% ^' e}4 W2 E( o" o: T! V! z1 y% A* g( y
/ b3 _8 T" q5 K( ^: @' j! a
& Z1 Z6 V4 G7 [% s# r' y- L, g0 O5、静态内部类(线程安全)
描述:这种方式达到跟双重校验锁一样的效果,这种方式只适用于静态域的情况,双重校验锁可在实例域需要延迟初始化时使用
//静态内部类; R! N; Y9 e0 J* s' X
public class Singleton {8 p7 R9 r. A5 Y) P. Z& P
private static class SingletonHolder {9 Y3 |' |) ^, L, K/ U6 q! n
private static final Singleton INSTANCE = new Singleton();
* R' }/ F' |/ m }
% \; p1 W/ | ]: J
6 e. i9 b3 X; e$ O( H( x' }- M8 P private Singleton() {2 P1 ?: k- \' ^- W& H
- i4 w; ]; X7 y C# L
}* f$ n' G5 U5 G/ j% P* p2 s9 T
2 X: B. W2 d9 `3 V- K4 {
public static final Singleton getInstance() {
* `: P7 [: N1 O- `; M return SingletonHolder.INSTANCE;$ Z" P; u" ^5 e4 n% L; }
}
& [1 z5 E |6 n7 J3 w}& h7 k1 h5 m1 ~3 ]+ a
" s r5 J% |6 M( ?" ]5 s
6、枚举(线程安全)
描述:这种方式还没有被广泛采用,但是这种实现是单例模式的最佳方法。更简洁、自动支持序列化机制、绝对防止多次实例化
3 `* W( p' B, z0 ], V
//枚举5 t1 y( s$ s% T% M t; o
public enum Singleton {4 t( j5 `1 B7 f# |
INSTANCE;( z! y, g5 s# P7 Q% \8 z. @7 E
4 ], }, L4 h* D; c- B) K public void whateverMethod() {1 V O( o' F! T
3 o$ |* K4 n! k1 {
}
! S: _0 m7 u9 A- l. O9 B1 p}! j$ f, {2 u9 j7 o" l
3 T% g( b$ g' f2 g$ d$ l4 b" [ ?+ S9 P5 K6 v' O$ W4 j
总结
$ F# B4 N% ^, N! G7 n( R) e0 k# w8 d% o5 D
一般情况下,不建议使用第1种和第2种懒汉方式,建议使用第4种饿汉方式。只有在明确实现lazy loading时,才会使用第5种静态内部类方式。如果涉及到反序列化创建对象时,可以使用第6种枚举方式。如果有其他需求,可以考虑使用第3种双重校验锁方式。
2 E! r) N# P+ J+ XPS:开始面临着春招,好多面经都有说到设计模式。最常见的面试题就是讲一讲单例模式的实现和理解,所以我写一下,加深我对单例模式的理解和印象。觉得对你有帮助的话可以点点赞,谢谢啦~~~
4 t% J& X7 q" [/ E( w0 d————————————————1 ~' A1 Z9 n1 q! M2 n! \! H
9 v' k1 e5 S6 [" N' M- ~
$ H1 ]9 B; w" [
# `5 Y9 t% e; b& A7 H
( C4 B/ H1 l' s6 a% I/ M& k+ s7 _) O2 G; j, p+ d
7 z7 u/ g$ C2 f/ O% P4 \
7 Y* `1 @2 `! @# t" P$ ^& u8 F. h" ?& X
6 p- Q0 Q, l0 E& d% J原文链接:https://blog.csdn.net/weixin_37686415/article/details/105164764( O/ E. }7 U- V$ y
* l9 h* u+ ~5 {5 `# J# h. N( G! w' `# c: v/ Q. M" h9 \' t9 c, H
作者: 1091597757 时间: 2020-4-1 18:08
厉害了!!!!!!!!!!$ O+ i+ a6 n1 U h+ n, y; C
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |