您的位置:首页 > 编程语言 > Java开发

Java线程安全的单例模式的几种实现

2014-11-03 00:48 555 查看
线程安全的单例模式实现有几种思路

1、饿汉式

Java

123456789public class Singleton { private final static Singleton INSTANCE = new Singleton(); private Singleton() { } public static Singleton getInstance() { return INSTANCE; }}
2、借助内部类Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public
class
Singleton
{




private
Singleton()
{
}




private
static
class
SingletonHolder
{

private
final
static
Singleton
INSTANCE
=
new
Singleton();


}




public
static
Singleton
getInstance()
{

return
SingletonHolder.INSTANCE;


}

}



属于懒汉式单例,因为Java机制规定,内部类SingletonHolder只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的。内部类加载的时候实例化一次instance。

3、普通加锁解决

Java

123456789101112131415public class Singleton { private static Singleton instance = null; private Singleton() { } public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }} 虽然解决了线程安全问题,但是每个线程调用getInstance都要加锁,我们想要只在第一次调用getInstance时加锁,请看下面的双重检测方案
4、双重检测,但要注意写法Java

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

public
class
Singleton
{


private
static
Singleton
instance
=
null;




private
Singleton()
{
}




public
static
Singleton
getInstance()
{

if(instance
==
null)
{


synchronzied(Singleton.class)
{

Singleton
temp
=
instance;

if(temp
==
null)
{


temp
=
new
Singleton();


instance
=
temp

}


}

}



return
instance;


}

}



由于指令重排序问题,所以不可以直接写成下面这样:

public
class
Singleton
{


private
static
Singleton
instance
=
null;




private
Singleton()
{
}




public
static
Singleton
getInstance()
{

if(instance
==
null)
{


synchronzied(Singleton.class)
{

if(instance
==
null)
{


instance
=
new
Singleton();

}


}

}



return
instance;


}

}



但是如果instance实例变量用volatile修饰就可以了,volatile修饰的话就可以确保instance
=
new
Singleton();对应的指令不会重排序,如下的单例代码也是线程安全的:

public
class
Singleton
{


private
static
volatile
Singleton
instance
=
null;




private
Singleton()
{
}




public
static
Singleton
getInstance()
{

if(instance
==
null)
{


synchronzied(Singleton.class)
{

if(instance
==
null)
{


instance
=
new
Singleton();

}


}

}



return
instance;


}

}

如果单体模式继续扩展为N元单体模式,那就是对象池模式了

赞1

分享到:QQ空间新浪微博腾讯微博微信更多0

本文固定链接: http://www.itjhwd.com/javaxianchengdanli/

转载请注明: IT江湖 2014年04月22日 于 IT江湖 发表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: