博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java的单例模式实现
阅读量:6955 次
发布时间:2019-06-27

本文共 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());
    
}
 
}

  1. 扩展 

    定义一个表示总统的类型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());
 
    
}
 
}
本文转自 许大树 51CTO博客,原文链接:http://blog.51cto.com/abelxu/1965630,如需转载请自行联系原作者
你可能感兴趣的文章
JSP三种常用注释
查看>>
iOS开发——高级技术&地图功能的实现
查看>>
SVN服务器搭建和使用(一)
查看>>
Android Studio 默认的快捷键
查看>>
FindWindow 查找窗口
查看>>
3027 线段覆盖 2
查看>>
JDBC处理文本和二进制文件
查看>>
菜单联动 加翻页
查看>>
GDB中打印ART基础类
查看>>
DFS-C
查看>>
POJ-2698-八皇后问题
查看>>
MySQL免安装版配置问题
查看>>
MySQL索引之B+树
查看>>
easyui中 combogrid控件的loadData方法加载本地数据
查看>>
Android实战技巧:消息循环与Looper
查看>>
android-audioRecord
查看>>
apache 访问权限基本设置
查看>>
jQuery的deferred对象详解
查看>>
python基础知识~ 序列化
查看>>
函数作业
查看>>