Redian新闻
>
thread safe Singleton 的几种方法?
avatar
thread safe Singleton 的几种方法?# Java - 爪哇娇娃
s*e
1
方法1:
最简单的 public static synchronized getInstance()
方法2:
一次面试中,面试官让我再举出一种方法,我取出了用 inner class 的方法, 以前在
wiki 上看到的:
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
http://en.wikipedia.org/wiki/Singleton_pattern
但是面试官说这种方法是错的~~~~~~~~
方法3:
貌似还有一种方法是:
public class Singleton {
public final static Singleton INSTANCE = new Singleton();
private Singleton() {
avatar
h*0
2
方法2之所以错,是不是因为外部类不能访问内部类的private成员?



【在 s*******e 的大作中提到】
: 方法1:
: 最简单的 public static synchronized getInstance()
: 方法2:
: 一次面试中,面试官让我再举出一种方法,我取出了用 inner class 的方法, 以前在
: wiki 上看到的:
: private static class SingletonHolder {
: private static final Singleton INSTANCE = new Singleton();
: }
: public static Singleton getInstance() {
: return SingletonHolder.INSTANCE;

avatar
s*e
3
外部只能访问 public getInstance()...
http://en.wikipedia.org/wiki/Singleton_pattern
wiki 上说这种方法是 thread safe 的,所以我很困惑。。

【在 h*****0 的大作中提到】
: 方法2之所以错,是不是因为外部类不能访问内部类的private成员?
:
: 在

avatar
h*0
4
这种方法确实thread safe,我的意思是inner class的private成员是不是不可以直接
得到?能编译通过吗?

【在 s*******e 的大作中提到】
: 外部只能访问 public getInstance()...
: http://en.wikipedia.org/wiki/Singleton_pattern
: wiki 上说这种方法是 thread safe 的,所以我很困惑。。

avatar
A*o
5
any cluster safe singletons?



【在 s*******e 的大作中提到】
: 方法1:
: 最简单的 public static synchronized getInstance()
: 方法2:
: 一次面试中,面试官让我再举出一种方法,我取出了用 inner class 的方法, 以前在
: wiki 上看到的:
: private static class SingletonHolder {
: private static final Singleton INSTANCE = new Singleton();
: }
: public static Singleton getInstance() {
: return SingletonHolder.INSTANCE;

avatar
s*e
6
compile 通过了

【在 h*****0 的大作中提到】
: 这种方法确实thread safe,我的意思是inner class的private成员是不是不可以直接
: 得到?能编译通过吗?

avatar
m*t
7

Define cluster safe first. ;-)

【在 A**o 的大作中提到】
: any cluster safe singletons?
:
: 在

avatar
m*t
8
The subject is wrong to begin with. The plain vanilla singleton
pattern doesn't have to do with thread-safety whatsoever, because
it's as simple as:
public class Singleton {
....private static final Singleton INSTANCE = new Singleton();
....private Singleton() {}
....public static getInstance() { return INSTANCE; }
}
The part where we put the initialization into getInstance() is
called Lazy Initialization, which is a separate pattern. And that's
where thread-safe might be a concern - only when r

【在 s*******e 的大作中提到】
: 方法1:
: 最简单的 public static synchronized getInstance()
: 方法2:
: 一次面试中,面试官让我再举出一种方法,我取出了用 inner class 的方法, 以前在
: wiki 上看到的:
: private static class SingletonHolder {
: private static final Singleton INSTANCE = new Singleton();
: }
: public static Singleton getInstance() {
: return SingletonHolder.INSTANCE;

avatar
g*g
9
I believe when you declare
private static final Singleton INSTANCE = new Singleton();
the instance is created when you load the class, not when you
call getInstance, so it's not lazy initialization and it should
be thread safe.

【在 m******t 的大作中提到】
: The subject is wrong to begin with. The plain vanilla singleton
: pattern doesn't have to do with thread-safety whatsoever, because
: it's as simple as:
: public class Singleton {
: ....private static final Singleton INSTANCE = new Singleton();
: ....private Singleton() {}
: ....public static getInstance() { return INSTANCE; }
: }
: The part where we put the initialization into getInstance() is
: called Lazy Initialization, which is a separate pattern. And that's

avatar
s*e
10
哦,这样的话,方法2 用了inner class 再 wrap 一下纯属多余。。难怪面试官不满意
。。

【在 g*****g 的大作中提到】
: I believe when you declare
: private static final Singleton INSTANCE = new Singleton();
: the instance is created when you load the class, not when you
: call getInstance, so it's not lazy initialization and it should
: be thread safe.

avatar
h*0
11
no, for inner class, it should be loaded when you first use it.

【在 g*****g 的大作中提到】
: I believe when you declare
: private static final Singleton INSTANCE = new Singleton();
: the instance is created when you load the class, not when you
: call getInstance, so it's not lazy initialization and it should
: be thread safe.

avatar
g*g
12
It's about where you initialize it, not where you declare it.
Static initialization is only created once when you load it,
regardless what instance of class you are creating.

【在 h*****0 的大作中提到】
: no, for inner class, it should be loaded when you first use it.
avatar
A*o
13
talking about thread safe, what if different classloaders in the same jvm
are loading the same single class multiple times?
avatar
h*0
14
no, inner class is different.
try:
class A {
static {
System.lout.println("initializing A");
}
static class InnerA {
static {
System.out.println("initializing InnerA");
}
}
}
public class B {
public static void main(String[] args) {
System.out.println("start main");
A a = new A();
A.InnerA ia = new A.InnerA();
}
}
avatar
a*i
15
3和1有什么区别?
你在找工作?找到没?



【在 s*******e 的大作中提到】
: 方法1:
: 最简单的 public static synchronized getInstance()
: 方法2:
: 一次面试中,面试官让我再举出一种方法,我取出了用 inner class 的方法, 以前在
: wiki 上看到的:
: private static class SingletonHolder {
: private static final Singleton INSTANCE = new Singleton();
: }
: public static Singleton getInstance() {
: return SingletonHolder.INSTANCE;

avatar
m*i
16
2 is an example in "Thinking in Java", I am pretty sure it works. The
wrapping class will be initialized exactly once, when it is referenced for
the first time. So 2 is singleton + lazy initialization.
avatar
s*e
17
方法1:
public class Singleton
{
private static Singleton INSTANCE = null;
private Singleton() {}
public static synchronized Singleton getInstance()
{
if(INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
}
1 和3 还是有区别的吧,3 没用 Synchronized keyword.
嗯,我已经找到了

【在 a****i 的大作中提到】
: 3和1有什么区别?
: 你在找工作?找到没?
:
: 在

avatar
c*t
18

Nope, this is in fact problematic.

This is correct. Your interviewer was WRONG.

【在 s*******e 的大作中提到】
: 方法1:
: public class Singleton
: {
: private static Singleton INSTANCE = null;
: private Singleton() {}
: public static synchronized Singleton getInstance()
: {
: if(INSTANCE == null)
: INSTANCE = new Singleton();
: return INSTANCE;

avatar
c*t
19
method 1 is problematic. Do not do so.

【在 s*******e 的大作中提到】
: 方法1:
: public class Singleton
: {
: private static Singleton INSTANCE = null;
: private Singleton() {}
: public static synchronized Singleton getInstance()
: {
: if(INSTANCE == null)
: INSTANCE = new Singleton();
: return INSTANCE;

avatar
s*e
20
Why? I thought it is the most common thread safe solution.

【在 c*****t 的大作中提到】
: method 1 is problematic. Do not do so.
avatar
k*r
21
3不需要synchronized吧,class load的时候初始化

【在 s*******e 的大作中提到】
: Why? I thought it is the most common thread safe solution.
avatar
s*n
22
#3 is simple, direct, efficient, and correct.
Then why would people bother to invent alternative methods?
The argument is that #3 could have the singleton instance created before
anybody asks for it. One could be referencing some other stuff in the class,
and that triggers the initialization of the class, hence the creation of
the singleton - which could be unwanted at that point.
This argument is very weak. A singleton class is designed to serve its
features through the singleton instance, it i
avatar
A*o
23
hmmm... the singleton pattern has been updated again.
last time i read wikipedia, it was still using
volatile as 5.0 and or later standard impl.

class,

【在 s******n 的大作中提到】
: #3 is simple, direct, efficient, and correct.
: Then why would people bother to invent alternative methods?
: The argument is that #3 could have the singleton instance created before
: anybody asks for it. One could be referencing some other stuff in the class,
: and that triggers the initialization of the class, hence the creation of
: the singleton - which could be unwanted at that point.
: This argument is very weak. A singleton class is designed to serve its
: features through the singleton instance, it i

avatar
z*0
24
can you explain why?

【在 c*****t 的大作中提到】
: method 1 is problematic. Do not do so.
avatar
i*c
25
go check the book headfirst design pattern
http://books.google.com/books?id=LjJcCnNf92kC&printsec=frontcover&dq=headfirst+design+patterns&ei=3JL7SrHBC5XKkASiy4CZDw#v=onepage&q=headfirst%20design%20patterns&f=false



【在 s*******e 的大作中提到】
: 方法1:
: public class Singleton
: {
: private static Singleton INSTANCE = null;
: private Singleton() {}
: public static synchronized Singleton getInstance()
: {
: if(INSTANCE == null)
: INSTANCE = new Singleton();
: return INSTANCE;

avatar
k*r
26
I'm assuming a problem with #3 is that you won't get
to handle exceptions that happen during creation of
the singleton object.

【在 s******n 的大作中提到】
: #3 is simple, direct, efficient, and correct.
: Then why would people bother to invent alternative methods?
: The argument is that #3 could have the singleton instance created before
: anybody asks for it. One could be referencing some other stuff in the class,
: and that triggers the initialization of the class, hence the creation of
: the singleton - which could be unwanted at that point.
: This argument is very weak. A singleton class is designed to serve its
: features through the singleton instance, it i

avatar
m*t
27
I don't get your last paragraph - what makes you think the jvm
_must_ be doing double check locking?
As for Singleton, I really think that it is an outdated pattern.
With Dependency Injection, you almost never ever need
to use Singleton.

class,

【在 s******n 的大作中提到】
: #3 is simple, direct, efficient, and correct.
: Then why would people bother to invent alternative methods?
: The argument is that #3 could have the singleton instance created before
: anybody asks for it. One could be referencing some other stuff in the class,
: and that triggers the initialization of the class, hence the creation of
: the singleton - which could be unwanted at that point.
: This argument is very weak. A singleton class is designed to serve its
: features through the singleton instance, it i

avatar
T*e
28
According to Head First's Design Pattern, #1 has a performance issue (I
guess this is the point of the above gurus) and can be modified into:
public class Singleton {
___ private volatile static Singleton s;
___ private Singleton() {}
___ public static Singleton getInstance() {
___ ___ if (s == null) {
___ ___ ___ synchronized (Singleton.class) {
___ ___ ___ ___ if (s == null) s = new Singleton();
___ ___ ___ }
___ ___ }
___ ___ return s;
___ }
}
Key points:
1. Lazy initialization
2. volatile
3.
avatar
g*e
29
最后一种不是最简单吗,有什么问题

【在 T*****e 的大作中提到】
: According to Head First's Design Pattern, #1 has a performance issue (I
: guess this is the point of the above gurus) and can be modified into:
: public class Singleton {
: ___ private volatile static Singleton s;
: ___ private Singleton() {}
: ___ public static Singleton getInstance() {
: ___ ___ if (s == null) {
: ___ ___ ___ synchronized (Singleton.class) {
: ___ ___ ___ ___ if (s == null) s = new Singleton();
: ___ ___ ___ }

avatar
A*o
30
doesn't work before java 5.0
but i'll use this rather than the private class one
if i need my singleton.

【在 T*****e 的大作中提到】
: According to Head First's Design Pattern, #1 has a performance issue (I
: guess this is the point of the above gurus) and can be modified into:
: public class Singleton {
: ___ private volatile static Singleton s;
: ___ private Singleton() {}
: ___ public static Singleton getInstance() {
: ___ ___ if (s == null) {
: ___ ___ ___ synchronized (Singleton.class) {
: ___ ___ ___ ___ if (s == null) s = new Singleton();
: ___ ___ ___ }

avatar
s*c
31
exactly.这是唯一的真正thread safe的方法。

【在 g*****g 的大作中提到】
: I believe when you declare
: private static final Singleton INSTANCE = new Singleton();
: the instance is created when you load the class, not when you
: call getInstance, so it's not lazy initialization and it should
: be thread safe.

avatar
c*n
32
能解释下为什么要volatile么?
还有谁来总结下这几个方法?好像各位的看法不一阿

【在 T*****e 的大作中提到】
: According to Head First's Design Pattern, #1 has a performance issue (I
: guess this is the point of the above gurus) and can be modified into:
: public class Singleton {
: ___ private volatile static Singleton s;
: ___ private Singleton() {}
: ___ public static Singleton getInstance() {
: ___ ___ if (s == null) {
: ___ ___ ___ synchronized (Singleton.class) {
: ___ ___ ___ ___ if (s == null) s = new Singleton();
: ___ ___ ___ }

avatar
y*u
33
volatile prevents stack cache

【在 c*********n 的大作中提到】
: 能解释下为什么要volatile么?
: 还有谁来总结下这几个方法?好像各位的看法不一阿

avatar
c*n
34
我记得如果一个var出现在synchonized block中的话就不需要volatile了,是这样的吧?

【在 y***u 的大作中提到】
: volatile prevents stack cache
avatar
s*e
35
that is right. volatile guarantee consistency via memory barrier but not
atomic, while synchronized provides both with performance penalty.
Singlton pattern used to be a popular pattern in java world when object
creation was expensive (jvm 1.4 and before). but with 1.5 and latter,
performance should not be of disadvantage of operator new if the class is
stateless.
The biggest problem for singleton is really about tightly coupling and hard
to mock for testing.
If you think you have to use singlet

【在 c*********n 的大作中提到】
: 我记得如果一个var出现在synchonized block中的话就不需要volatile了,是这样的吧?
avatar
W*i
36
需要 synchronized
avatar
r*l
37
Agreed.

class,

【在 s******n 的大作中提到】
: #3 is simple, direct, efficient, and correct.
: Then why would people bother to invent alternative methods?
: The argument is that #3 could have the singleton instance created before
: anybody asks for it. One could be referencing some other stuff in the class,
: and that triggers the initialization of the class, hence the creation of
: the singleton - which could be unwanted at that point.
: This argument is very weak. A singleton class is designed to serve its
: features through the singleton instance, it i

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。