数学建模社区-数学中国
标题: 浅谈单例模式的实现方式 [打印本页]
作者: 杨利霞 时间: 2020-3-30 17:20
标题: 浅谈单例模式的实现方式
浅谈单例模式的实现方式1 N& C8 v9 C9 n/ u! N
单例模式(来自菜鸟教程)7 q% C- E3 _2 ~3 i x% {
3 `- Y% @/ B/ t7 E单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
: P0 U# @, H$ X# J. {单例模式的要求
3 \) T N, Y' O/ U! s& d/ d) H2 f6 G- A) O) Q
构造方法必须私有化(确保只有自己能创建)" {5 j, s7 j1 v. l
以静态方法返回实例(外界不能通过new来获取到对象)
4 D2 X+ O+ [1 R' j2 o& d确保对象实例只有一个(只对类进行一次实例化,以后都直接获取第一次实例化的对象) n; }6 H2 G' N. P+ i5 @/ G
单例模式的实现
# N, J G+ q! g- R1 [: ?+ O. E' }0 y: J- {1 \
1、懒汉式(线程不安全)7 ]# ~2 ]. t x( M" e! l7 ~- l5 Q
3 V; H6 t5 S, L5 A& |% j' W描述:这种方式是最基本的实现方式,但是不支持多线程。因为没有加锁,在多线程不能正常工作, g4 {- |, s' ]) j: ^" V7 G: W
//懒汉式(线程不安全)1 _) J7 ~2 B3 q) L
public class Singleton { 4 ]1 b* M7 ^( r0 _# R
private static Singleton instance; ! L. s$ [. D! H' p6 k
- G+ X2 p% [* e n( `$ y/ ^ X0 X
private Singleton (){}
; i: N( X& s$ S' z0 w4 t
0 b0 w! U7 l, K3 x public static Singleton getInstance() { ( M+ \ r B0 ?+ l; X$ l
if (instance == null) {
/ D5 z0 h6 ]0 ~ instance = new Singleton();
" @7 b* R: p) t' [6 g; d }
5 M5 |9 @9 C# T9 j) v" v& @ return instance;
# {8 q. P* e8 Z, n K% G* k }
$ I1 e1 J: D4 {! S- T3 D}
! ]3 Q" A! ^' P3 A# \2、懒汉式(线程安全)
描述:能够在多线程下正常工作,但是,效率极低
//懒汉式(线程安全)
6 |/ ?6 C% e* |2 V3 V9 W \% |public class Singleton {
4 Z5 G8 H5 ^ b3 M$ Z' Q private static Singleton instance; : k5 T" Q8 K6 I) ]2 T1 q
* j+ }$ |/ @. i8 }
private Singleton (){} . w- H/ c. f: p% J: F
) @' k2 R6 |" x- r public static synchronized Singleton getInstance() {
g; i7 R! f/ N: ?7 e if (instance == null) {
3 r8 V X+ T1 L& i8 W2 A# y instance = new Singleton(); 0 T- Y( ` v7 x1 F: ~
} + J }- d3 c7 ^" o% X ^% k% i& z
return instance;
/ [5 h& |- G7 d( P6 a$ V5 z+ C }
1 B" }2 P1 p6 V5 O3 b7 D! B3 i}
2 b' k$ B: X5 U( C$ A/ p$ \# J
" ?0 A- }+ D y3、双重校验锁(DCL,即double-checked locking)(线程安全)
描述:对懒汉式(线程安全)的优化,采用双锁的机制,安全且在多线程情况下能保持高性能
! `% ~! A# S7 m$ i; x
//双重校验锁5 n9 Y ~/ e9 w9 L# w C. X
public class Singleton {- G% |; I5 I$ q+ b8 H3 m, O
private volatile static Singleton instance;% r* T1 g0 G3 l2 k
5 R Z/ ?9 v, G9 C$ }4 |2 l; U private Singleton() {0 \; d7 {7 G% p- O% M
" | K9 _ r/ b7 N }8 q2 G7 M# J* Q
2 m/ D) _# B& n9 O' y [( j$ S: t
public static Singleton getInstance() {
: i! X6 r& b2 T a) ~0 ^2 x if (instance == null) {; n; U2 Z( X, ` M) [- K( T8 _
synchronized (Singleton.class) {3 u$ q: X: n6 I6 K9 J
if (instance == null) {
7 m! a! z& m% g" M) V0 ^/ o instance = new Singleton();: ]* A: x2 t: g- N: S: C* N: ?6 m
}
7 `+ B( ~) J( w' G1 | D }
% u3 z6 l% x7 J, j- U }6 l' F/ J4 A# `& w. d5 m7 G
return instance;9 t1 E5 I# m+ [8 @/ @" ^, R
}
3 s8 U( a* M1 w' L$ s) P3 ^& h}
8 q3 Z! C& C( W5 s, U' }( e5 X% F& Y: ]% l
7 L* n3 j% Z+ Y2 G0 K
4、饿汉式(线程安全)
描述:这种方式比较常用,但容易产生垃圾对象
; ^' c8 y, J6 B/ [. F//饿汉式
: @5 u6 Y% R8 K0 H) ~7 g; Bpublic class Singleton {
% w8 t0 y# _: f4 D, l6 R, p private static Singleton instance = new Singleton();# I7 i& j1 q7 _( v
# h1 T. ?1 |. ]& E% z' w" Y private Singleton() { V) t, J& M7 O& N+ r. @9 q1 ]1 \
. F2 e" u1 c; a4 |5 k. f }$ O, z7 {- b. N/ C* t, D
2 U4 l6 q3 i5 _. n/ N/ g0 c( G5 k public static Singleton getInstance() {. W( S; R: M/ z! l% G2 R8 F" n
return instance;
# g4 ^4 U* h% }5 z) }& L" f- Y }
2 m# F$ y! A& [/ ^5 T}8 z/ `) L9 I M# D, ], l1 V% f3 a
2 P" v: m: x% d% Z; l
& @2 x; m) M) L. d! u7 X* H c
5、静态内部类(线程安全)
描述:这种方式达到跟双重校验锁一样的效果,这种方式只适用于静态域的情况,双重校验锁可在实例域需要延迟初始化时使用
//静态内部类, n( s! h; |" H5 ~* F4 d/ f
public class Singleton {! d9 n& z+ N3 X% ]
private static class SingletonHolder {
' a+ n! D- h4 D; l" j3 C4 B0 }" Y: o private static final Singleton INSTANCE = new Singleton();
: b5 x4 y: s0 Z- s }
8 G$ A; @4 E5 w4 s* d; `: I; H
" M; J" R0 @' ?6 ?' | private Singleton() {2 k5 @4 `; g! ~/ z3 T4 F/ s S
& H0 p& N' T2 {' R! H' w }
9 k* f, R. f2 c7 F i# Q) g1 b
, c0 b5 Q, v6 d$ \. f. b( f public static final Singleton getInstance() {
* j( ?5 q% p, F/ a return SingletonHolder.INSTANCE;: o- u* y: b+ Q3 j" y
}
+ ?& ?) \' t; @0 e% `& Z) ^/ q}
' U! Q9 x4 u* v/ `" j# ?. L2 t2 V
6、枚举(线程安全)
描述:这种方式还没有被广泛采用,但是这种实现是单例模式的最佳方法。更简洁、自动支持序列化机制、绝对防止多次实例化
7 Z+ j6 a$ ~: q5 u( v//枚举
( u/ H) F7 Y( V# L% ?1 n! ypublic enum Singleton {! B0 S* e- U" `, E* C K- u
INSTANCE;% z* T, K6 F- I2 L# C
+ Z) m. A4 Y5 k; N/ q. S public void whateverMethod() {4 [( {( x3 r2 B. \0 r) X0 l
2 \, z3 d+ G8 {! p
}3 U2 T- @9 t' O |) h' u1 O5 L8 k
}' c g1 w$ v$ ^. H2 o" a7 y! M' l
$ I2 A& a7 ?9 w0 a1 B! a8 `
- c, s( {) U2 q" n" Y v总结- O ?$ o# I! T) h; V3 w" E
5 p! n7 k. F: k3 M一般情况下,不建议使用第1种和第2种懒汉方式,建议使用第4种饿汉方式。只有在明确实现lazy loading时,才会使用第5种静态内部类方式。如果涉及到反序列化创建对象时,可以使用第6种枚举方式。如果有其他需求,可以考虑使用第3种双重校验锁方式。
0 }+ @+ U/ ~$ Q5 x1 z! I1 O7 {PS:开始面临着春招,好多面经都有说到设计模式。最常见的面试题就是讲一讲单例模式的实现和理解,所以我写一下,加深我对单例模式的理解和印象。觉得对你有帮助的话可以点点赞,谢谢啦~~~
# C, W0 w; t: ]& U# J# z6 J————————————————3 c- x: \: u) V5 q j8 `
U6 j0 H4 I/ U; [9 v1 }& M" H& p3 o( w6 i$ p
O+ f! y U+ x0 H$ i/ E
5 }& d5 l' x1 x3 G2 z. N7 G
9 b, O( D" q4 m/ h1 D! V
$ ~4 Y/ m* t* x7 m$ N- x
4 ?/ D4 ^' o* a, ~" Z2 C! a/ i9 D- |0 E5 Q* J& b
$ H0 e: h5 j4 n }9 S- K3 s1 }4 e" r原文链接:https://blog.csdn.net/weixin_37686415/article/details/105164764
' S' n( _8 E+ l( ]& w5 x6 j+ x+ ~/ o2 d% [2 O$ _; i
/ ~2 g5 C7 {# n, u
作者: 1091597757 时间: 2020-4-1 18:08
厉害了!!!!!!!!!!$ i' i5 o$ g/ M6 I5 a" |
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |