数学建模社区-数学中国
标题: 浅谈单例模式的实现方式 [打印本页]
作者: 杨利霞 时间: 2020-3-30 17:20
标题: 浅谈单例模式的实现方式
浅谈单例模式的实现方式" `( e F1 h1 D' U/ X( i* {
单例模式(来自菜鸟教程)
2 }5 U9 h/ T8 G; A
5 M" g4 t% {1 E单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
+ B! _) n) d2 t. Q( |单例模式的要求
1 M* _% @1 W7 `1 v1 E) z: @
/ J6 X% g8 t. m% a构造方法必须私有化(确保只有自己能创建), x3 K( r- ~/ j& v0 `+ v
以静态方法返回实例(外界不能通过new来获取到对象). @! q9 a. ~* {. I) p
确保对象实例只有一个(只对类进行一次实例化,以后都直接获取第一次实例化的对象)
6 x' z2 |1 Q) V; x: h( x单例模式的实现
, X( E3 p: `# {/ n. [6 L/ X" i5 F. `5 \: u
1、懒汉式(线程不安全)1 w" Z8 {1 c+ C4 Q: n
5 ?9 p7 G/ a+ e, P
描述:这种方式是最基本的实现方式,但是不支持多线程。因为没有加锁,在多线程不能正常工作7 S" r1 r3 V0 B3 J" V" Y' s
//懒汉式(线程不安全)6 q! }8 |' I9 j
public class Singleton { , D$ R7 Y2 L& ?$ ^" L' n8 j I6 [4 M
private static Singleton instance;
7 [7 v. l* J7 p
$ m1 G& k8 }' f$ v1 k8 ]2 Y private Singleton (){} - L0 x- r- @4 }8 J
6 ?! B m5 q$ S8 N7 D0 K5 g( ?3 D public static Singleton getInstance() { . q6 i ? L& k; ?, R
if (instance == null) { 3 V H9 a/ p; {( x& P' h
instance = new Singleton(); 9 a6 ?2 O9 X/ O8 C' u/ s
} " `9 Q$ m* e, z/ K) G/ v5 u
return instance; & ?) S# v# S; E' r
} 5 O% k) t, M8 R! m
}
" c* {- ]3 W9 w% p+ ^2、懒汉式(线程安全)
描述:能够在多线程下正常工作,但是,效率极低
//懒汉式(线程安全)7 w3 @2 ?+ |: K0 O: V, b
public class Singleton { . F6 f. ~- Q8 K1 B
private static Singleton instance; # d% W( ?0 _( f& W2 u0 J) ~9 ]
) L. D' v9 O- n2 f5 q' {
private Singleton (){}
6 s) u5 D( y5 z" ~4 ?4 k5 e$ I' M& l, Z
public static synchronized Singleton getInstance() { ) Y; j2 Z' p2 y/ n( t
if (instance == null) {
. t5 s0 ]! o4 D' h instance = new Singleton(); . S- I5 n+ s: X; G% ?
}
T7 ^! Z& k5 M, p return instance; n! F2 h; X; @1 X
}
& {5 [) ~( c* ^}
A" t# F3 o+ i6 M( m8 k, f4 }+ m
7 h3 V9 `! a" U4 {$ N" u5 g3、双重校验锁(DCL,即double-checked locking)(线程安全)
描述:对懒汉式(线程安全)的优化,采用双锁的机制,安全且在多线程情况下能保持高性能
, P' ]: g) D4 }0 ]% R3 f# a
//双重校验锁
, X* V( O/ } v) Fpublic class Singleton {
9 ^( B) O, W1 H1 H private volatile static Singleton instance;
: F* [- d/ o( b' c9 ?& e; E _8 g8 j9 `; ], K$ @. E
private Singleton() {# ^: S& U# w; ~; D. c
* g: F1 @& z* n( ] }
! j$ e$ s$ D3 J B" f8 B/ W6 Q! h+ c+ ~, _
public static Singleton getInstance() {- z* j5 A W9 M: G* o1 p
if (instance == null) {( @3 _% L8 S6 B
synchronized (Singleton.class) {
0 _7 W4 H! f N! ` P if (instance == null) {
* ^% f2 J, h. ]" w3 f- p instance = new Singleton();1 M M$ q+ M8 `- C
}$ L- s% S% k7 D% F
}! L4 L. ?2 y' t5 N4 [) {
}) G! w, ?/ _5 j* k0 ^; X$ D
return instance;
$ S- L' f C, I1 b- A }- s7 |0 h4 I. H2 C
}
d! |; E/ z) ~' J2 g3 }8 g5 F5 b+ x) u4 K0 {
$ s6 }6 Y9 t) k, s
4、饿汉式(线程安全)
描述:这种方式比较常用,但容易产生垃圾对象
: j) ]* z8 T# y, ~& ?3 n/ S6 r" Y//饿汉式) P2 `# x' x& v9 f& E
public class Singleton {
" f8 V# E: _$ U. X' K' a private static Singleton instance = new Singleton();
- q! @ V" A( m, G* Q8 d: B# b% m) `
/ o, W! {0 k1 c% S; r private Singleton() {. j- c, z2 [! S9 @
1 d& w0 C8 T# G0 S
}
9 r, [6 I- r0 T, {7 A! Q7 f* y% G$ U
: L. {" h6 y8 I. d$ o. g9 [ public static Singleton getInstance() {
, k9 i- V! Y! b* z& s l% W# T return instance;* N* [8 i* V& v6 B$ P) K: S
}
- @1 @& I4 r* m( v+ J}, L" a- g: u, a: M
3 W, y t, u* J% y
* q! K- j) x: F
5、静态内部类(线程安全)
描述:这种方式达到跟双重校验锁一样的效果,这种方式只适用于静态域的情况,双重校验锁可在实例域需要延迟初始化时使用
//静态内部类
: m/ x( b5 M4 M! Q- J# H, \public class Singleton {% P" b7 g0 h# k1 v: h$ [; @
private static class SingletonHolder {
6 w$ w" J& J# x( y# @. G& X! Z% ? private static final Singleton INSTANCE = new Singleton();
, N' @3 t' v: ~ }
+ d% e4 z" k, ] j* p+ a6 s
$ R( F; W8 o( T. {0 s7 z% r% w7 V private Singleton() {
4 s) x. u5 U7 t3 R3 ~5 E
J( H3 s0 c! V- k% a }( V' y' N% V$ e+ \7 m
' y; q3 |$ e: e) k) r7 O } public static final Singleton getInstance() {
+ \3 H* g% l H( F6 s return SingletonHolder.INSTANCE;
/ L: E# L% x; E% ~ ?5 ? }- c/ [: |3 C. m' S$ E7 m2 u
}
. M$ t' Y3 a- [
3 y2 {0 r6 u5 U# D6、枚举(线程安全)
描述:这种方式还没有被广泛采用,但是这种实现是单例模式的最佳方法。更简洁、自动支持序列化机制、绝对防止多次实例化
" e. [$ M, { h, U. z
//枚举( w, Q `4 J, G( u) S/ c
public enum Singleton {
9 ]7 c3 J }2 e# f l INSTANCE;
% `& h. [; O& K9 Z
; j) q; X8 }- y6 U public void whateverMethod() {' w* f! }7 b! h
4 q/ W) p& b0 P7 ]7 W( R$ T( p }. ]( d' ]" K* M# B
}
, ^* \7 k6 k q. _8 j/ F4 `3 L2 D) v
+ X/ W! c; Q$ S1 o总结; s( u( j: E$ t& b
4 u/ l0 M ?1 m0 u* B5 B; i1 K' O
一般情况下,不建议使用第1种和第2种懒汉方式,建议使用第4种饿汉方式。只有在明确实现lazy loading时,才会使用第5种静态内部类方式。如果涉及到反序列化创建对象时,可以使用第6种枚举方式。如果有其他需求,可以考虑使用第3种双重校验锁方式。
" e" F6 C' b6 x# ^) L1 XPS:开始面临着春招,好多面经都有说到设计模式。最常见的面试题就是讲一讲单例模式的实现和理解,所以我写一下,加深我对单例模式的理解和印象。觉得对你有帮助的话可以点点赞,谢谢啦~~~) T6 K% v% W0 H& J
————————————————( t0 v& m6 ^# m' P* X& t; C
1 E0 f0 a2 b5 ]3 _7 D0 L5 n
* Q- i3 N) r; _: o. g- R3 V2 ^* P9 W# k
; v2 Q6 R7 k' u1 l# A
; Q$ V" o5 p: k6 ^1 W# M
0 V8 C! U$ O# b- S
; N% Z' @0 T9 W0 G+ X4 ^- q
! M$ w1 ~2 H v. i q9 t+ F' c
: l% D4 A" [3 |# M# l) `原文链接:https://blog.csdn.net/weixin_37686415/article/details/105164764
1 s; d% o* E3 H9 U
/ g% c! _9 Y* k0 W2 u' v0 u7 t v- C% W& L5 z# _& ~
作者: 1091597757 时间: 2020-4-1 18:08
厉害了!!!!!!!!!!
% r/ f% E4 X% Q* A/ n
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |