数学建模社区-数学中国
标题: 浅谈单例模式的实现方式 [打印本页]
作者: 杨利霞 时间: 2020-3-30 17:20
标题: 浅谈单例模式的实现方式
浅谈单例模式的实现方式$ x( X# q, o( W5 e3 A' K
单例模式(来自菜鸟教程)
# s+ j8 |' \3 t8 A% K8 ^9 N0 B
8 W q6 a* P1 X" l; A单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
; z4 I1 @) ~5 r1 {单例模式的要求( i) F- w9 A5 A& J& Z
, t8 s: f& H( O- H! j2 a; h1 G构造方法必须私有化(确保只有自己能创建)
* X6 k. h" E1 B; [' i, a! a以静态方法返回实例(外界不能通过new来获取到对象): H+ o" d4 J/ b) X1 ~' G" I
确保对象实例只有一个(只对类进行一次实例化,以后都直接获取第一次实例化的对象)- {2 o! m! k/ I0 F! n! T) [' M/ y
单例模式的实现; I9 C/ s! i3 I5 r. Z
' t3 m+ D) o. A* b! j1、懒汉式(线程不安全)9 R! ?9 {6 p- V" ` @7 @, B
* a$ [/ g: B2 b2 J9 @ Z描述:这种方式是最基本的实现方式,但是不支持多线程。因为没有加锁,在多线程不能正常工作 g/ j) l/ }4 q
//懒汉式(线程不安全)! u; W7 M2 h* g3 C Q3 {! {! `2 k
public class Singleton {
& v5 j: G. F- z+ \0 h& A private static Singleton instance; & S% u F7 h& }
( \ j2 ^9 Z. @ S3 L! K
private Singleton (){}
, }" V6 h% w' Z/ K. p$ w4 R/ f. d7 i& `8 \
public static Singleton getInstance() { $ G8 v8 {2 U6 E& m X4 _
if (instance == null) { ) d; J6 f- w/ A" G& D: r* @3 u, r
instance = new Singleton(); " g4 O% Z2 E! |+ n6 p
} . C: P9 F& q5 E+ }+ a
return instance; 3 Y4 v3 O4 c3 i# C1 x
} 2 \; ]( O: V, M0 J7 x. b- B
}
0 Y* ]% K; V4 L8 @) e3 V2、懒汉式(线程安全)
描述:能够在多线程下正常工作,但是,效率极低
//懒汉式(线程安全)
( Z3 h. Q/ K0 M; [1 b2 L: l* Xpublic class Singleton { + v* D- r) u8 i$ E- k. Y3 r
private static Singleton instance;
/ i6 }6 S0 X& n! N7 t3 y2 t% U& y/ J3 A) i. \
private Singleton (){} $ M. z( c X/ F' A; @& j5 E/ d
2 K0 } }2 W* M5 }; M8 r public static synchronized Singleton getInstance() {
: h! u4 ^4 Z( s$ l+ F" }8 D if (instance == null) {
- A# z* x- H7 K0 R+ P) C; H( z instance = new Singleton();
, _, t u1 B' J5 W) A4 U } % H" p+ C" W, l! h6 t
return instance;
% b1 D' P5 X, i3 z } 8 p% M( U/ G( f5 Y* Y
}5 _: M1 b3 e7 a. s
& ~& {. |! {* v3、双重校验锁(DCL,即double-checked locking)(线程安全)
描述:对懒汉式(线程安全)的优化,采用双锁的机制,安全且在多线程情况下能保持高性能
6 a: k/ v5 \/ H; u) P9 I" w- }//双重校验锁
1 ?2 ^" J3 j% ?/ P. \! M$ K8 {public class Singleton { `. \6 }0 I( z+ }+ l* z' G; q
private volatile static Singleton instance;
! C* b; `9 j6 Q+ j+ c
7 O* ^/ D9 j0 U; \: |' z3 d( Q% ~ private Singleton() {
3 A5 s/ @- b2 X- m" @2 |* t! e1 A' V) b! i+ M2 I# I
}
7 Q& L2 y0 G; H5 S3 D& l0 F8 ~! ~, ]. O
public static Singleton getInstance() {* ]# r, X# m& \6 j% U
if (instance == null) {" e5 p5 E: \% m; [# w$ W: C+ s) m
synchronized (Singleton.class) {
7 d) h- y* j5 Z# {* {$ J if (instance == null) {
# v0 H; [9 j0 K- b' ^( R8 h4 ^ instance = new Singleton();1 Z& E$ J8 z9 q
}
: u0 X0 b+ u( X& O6 v% | }
1 K! V( @0 N0 `% n }0 Q0 f5 U& w, h6 ^! t9 V. \/ g& \
return instance;* |) [& J# n* r* X+ X) X! d
}' e$ y6 c- |6 Q2 G3 @2 U5 v$ b
}
1 \0 \# X# z( K7 L t: ] y7 c+ D: ~) h
9 L$ T$ @2 j% ?$ @7 z) e0 @7 r9 j1 L) T, ~
4、饿汉式(线程安全)
描述:这种方式比较常用,但容易产生垃圾对象
4 @8 ?# l v# z& B& a. C. |4 Q! y
//饿汉式
& |, B1 \4 ]3 ?+ Bpublic class Singleton {/ A# y6 Q+ M+ a% S, n' x
private static Singleton instance = new Singleton();5 e( c" c% d2 v$ P( m; K
1 ?* L7 A6 l+ n. }
private Singleton() {
+ h* s: ]# ?3 t( r0 ]
3 ?5 `& l; v3 q" ~1 m' Z9 g3 R }
+ @1 E& b2 R1 k0 n e0 m* w+ C5 P& O. ^
public static Singleton getInstance() {
, O' u, q$ N) `. A. d1 d$ T& m3 \ return instance;
1 e2 h6 x9 ~' q8 p' ] }
: Q( l' }. E6 b. ] t}
' }7 v( D% U# _- b l% \5 }+ f- M6 D* a$ R
1 [9 q. `* q) H! H6 x5 ?% a
5、静态内部类(线程安全)
描述:这种方式达到跟双重校验锁一样的效果,这种方式只适用于静态域的情况,双重校验锁可在实例域需要延迟初始化时使用
//静态内部类
$ }) y" I B# b" Q5 @! w9 wpublic class Singleton {
" m; o/ p) m( g. U1 J private static class SingletonHolder {
1 g$ Y4 b8 S) m# K" o private static final Singleton INSTANCE = new Singleton();# ^! ^2 d; n- ], _# P" f( B5 Z, I
}6 p$ m5 m# f! ]0 I3 P3 ]6 W
, F$ b( X" q$ p& Z4 ~$ X r) |
private Singleton() {
$ t7 p) y" d9 z+ l5 R9 t3 v3 x
C( J, z+ ^7 R' t9 M+ a" q/ t }
, r' q) x5 x3 {2 A; F" r7 J# C' \ K: @
public static final Singleton getInstance() {/ c$ {8 i. x6 U: p; Q
return SingletonHolder.INSTANCE;
: X9 Q5 d6 |$ @' R8 A5 s6 a: B }; n' l2 K- O) d0 ]4 `
} @8 l; a' Y% I7 o9 i
+ N+ i- `. F' B' \5 s6、枚举(线程安全)
描述:这种方式还没有被广泛采用,但是这种实现是单例模式的最佳方法。更简洁、自动支持序列化机制、绝对防止多次实例化
8 B5 O2 {$ ^2 @/ g; G1 {. M
//枚举" L2 `0 S$ |% w
public enum Singleton {
, m" {% l6 u5 {; G0 X INSTANCE;
, U- z8 O! n% {7 l9 c1 B/ k; G
2 `6 u, j5 K9 A/ e7 j5 ] public void whateverMethod() {
; V3 Z4 o, Q. H a& U
/ w m& b) t- b' X/ I+ B) X }& |. J+ k- R/ S6 }# L9 W
}
1 L* |+ e5 `) a' X- N" K; J: u) A0 _* t; \4 ^2 f/ I
e6 K3 t: K/ Y3 H( g总结9 ^, e# X1 z: p
# k( y* a6 s. ]0 C: A% y3 O
一般情况下,不建议使用第1种和第2种懒汉方式,建议使用第4种饿汉方式。只有在明确实现lazy loading时,才会使用第5种静态内部类方式。如果涉及到反序列化创建对象时,可以使用第6种枚举方式。如果有其他需求,可以考虑使用第3种双重校验锁方式。7 j' h0 d7 Z/ v; |
PS:开始面临着春招,好多面经都有说到设计模式。最常见的面试题就是讲一讲单例模式的实现和理解,所以我写一下,加深我对单例模式的理解和印象。觉得对你有帮助的话可以点点赞,谢谢啦~~~: X' E2 n7 v6 b4 T$ i- B
————————————————
1 d" c+ k& p! r+ n/ w
# R1 U: \* B. ~; e4 k' R
) F. p/ o- t( x4 F( i
: o' B+ i- m1 |1 H( `7 r% D; p: X+ F: q' b
P1 e+ o0 Q: d1 Z u; D
5 L1 b; k6 r0 x! f8 m2 G
' _/ }2 @( h# u# e0 z$ _2 U) Z2 h1 ^% E
( z0 w8 P3 `& C% d2 k' Q8 R9 e
原文链接:https://blog.csdn.net/weixin_37686415/article/details/105164764
" s7 o5 k1 p8 ]' O, [% N4 L6 c3 T. `+ t" ~! u- B+ ~8 F
# t2 D9 E" h8 W G9 [, H+ D
作者: 1091597757 时间: 2020-4-1 18:08
厉害了!!!!!!!!!!
' U) @7 q; j% `4 t! t0 [
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |