avatar
关于singleton# Java - 爪哇娇娃
s*l
1
在线试听
http://www.xiami.com/album/356069
语种 国语
唱片公司 艾迴唱片
发行时间 2009年11月
转自猫扑
http://ent.mop.com/music/3089102.shtml
又是13个月,信推出了新专辑《趁我》。如果还把信跟信乐团搅和在一起,似乎有点对
不起信,毕竟发行了四张个人专辑(其中一张是翻唱专辑),数量上已经与乐团持平,还
获得过金曲奖最佳男歌手的提名,音乐性也得到了肯定。将其称为定义为一个优秀男歌
手一点都不过分,但是歌迷怀旧,《死了都要爱》还是他们的心头最爱。
《死了都要爱》的影响力可与《青藏高原》相提并论,后者是中老年人一展歌喉的
杀手锏,前者则是年轻小孩一鸣惊人的必杀技。此种里程碑式的高度,也让单飞后的信
一直无法超越。信的高亢嗓音已经成了他的代号,听他的歌,人们总有种期待,他还可
以更高。新专辑《趁我》,信依旧亮出了自己的高音嗓子,开篇曲《回来》副歌中小小
一句“放不下可爱”足以挑起歌迷的听觉神经,往下听,一定有更惊心动魄的音阶出来
。只是继续播放的曲目让人们产生了疑惑,的确还是很高,只是相
avatar
c*1
2
【 以下文字转载自 Music 讨论区 】
发信人: cranberry521 (cranberry521), 信区: Music
标 题: 给大家哼个小曲:相逢是首歌
发信站: BBS 未名空间站 (Fri May 1 21:10:39 2009)
我来哼个小曲,呵呵。祝大家周末心情好!
最近在练习颤音,很明显还没有练好,呵呵。歌词被我稍作改动。这个曲子也比较适合
当作华尔兹舞曲呢。刚开始的伴奏有点宫廷舞曲的意思,呵呵。
作曲:张千一 作词:刘世新 演唱:俞静
翻唱:Cranberry521
连续剧《红十字方队》插曲
你曾对我说,
相逢是首歌,
眼睛是春天的海,
青春是绿色的河,
你曾对我说,
相逢是首歌,
眼睛是春天的海,
青春是绿色的河。
相逢是首歌,
同行是你和我,
心儿是年轻的太阳,
真诚也活泼。
相逢是首歌,
同行是你和我,
心儿是年轻的太阳,
真诚也活泼。
你曾对我说,
相逢是首歌,
分别是明天的路,
思念是生命的火。
相逢是首歌,
歌手是你和我,
心儿是永远的琴弦,
坚定也执着。
相逢是首歌,
歌手是你和我,
心儿是永远的琴弦,
坚定也执着。
啦啦啦啦啦
avatar
h*a
3
这是我第一次在美国画的国画。到了美国手痒,没有国画纸,没有墨。只有一只写字的
烂毛笔.有一次差一点扯厕所纸来画。这幅画是我用paper towel 画的。墨是用black
ink。
镜框是我才自己作的。
avatar
z*e
4
看到其它版面有人说这个pattern
单独拿出来说说我的两分钱
就我个人而言,我觉得这个pattern可以说是最简单
但是也可以说是最难的一个
因为陷阱太多,可松可紧,牵涉面很广,不少还是冷僻的东西
大概数了数
应该有8种方式
一个一个说
第一种,static instace = new Instance();
这种其实也是最常用的方式,eclipse上可以点击实现
不再赘述
第二种,enum{SINGLETON}
这种是现在比较流行的方式,大多数面试的人其实也就是问这种
这个好处在于连Serializable都实现了,坏处在于无法extends
下面这个是痛苦的开始
第三种,double check
这一种是最难的,要理解其背后的原因,需要深入多线程和byte code的实现中去
无论怎么check,jvm规范都不会阻止说把赋值操作提前
最后要用volatile干掉jvm尤其是jit的优化机制,才能保证在synchronized的时候
不会出现subtle多线程的冲突问题,灰常恶心,甚至测试中都都很难重现这种问题
面试时候如果出这种题,那就是纯粹刁难,move on吧
这已经不是一般难度的java问题了,是jvm实现的机制问题
第四种,static block
这种其实是第一种的变体,从jvm角度出发,两者其实是一样的
第五种,inner class
把第一种封装到一个内部静态类中去实现,以达到lazy init的目的
真心觉得没有必要,要是不用这个类的话
那个类根本不会在静态区被加载,自然也就不会去实例化那个instance
如果加载了,又不用,那只能说是除非其它的static方法很多
需要常用,但是又不想用这个instance的非static方法的时候……
wtf
以上五种是core java的东西
下面说一下其它三种jee的东西
第一种,spring的xml的scope="singleton"
第二种,annotation的@Singleton
第三种,guice的用法,bind(***.class).in(Scopes.SINGLETON);
从严格意义上说,这三个都不是实现
只是不同的使用和配置方法
除了第一种以外,其它两个应该不会太常见,尤其是最后一个
估计不会有人问起哈
所以java的singleton真不是一点点的深,水很深
后面可以带出很多东西,从jvm到ejb都可以带出来
遇到了之后要小心,我看有些例子甚至带出了awt……
我的天
avatar
w*F
5
汪峰怎么能和信比。。信的摇滚音色在当代华语世界里没人能比得上了。。不要说
still loving you或者always了,汪峰大概连《死了都要爱》都唱不好,他的唱法基本
就是老狼那种加上一些高音罢了。

【在 s******l 的大作中提到】
: 在线试听
: http://www.xiami.com/album/356069
: 语种 国语
: 唱片公司 艾迴唱片
: 发行时间 2009年11月
: 转自猫扑
: http://ent.mop.com/music/3089102.shtml
: 又是13个月,信推出了新专辑《趁我》。如果还把信跟信乐团搅和在一起,似乎有点对
: 不起信,毕竟发行了四张个人专辑(其中一张是翻唱专辑),数量上已经与乐团持平,还
: 获得过金曲奖最佳男歌手的提名,音乐性也得到了肯定。将其称为定义为一个优秀男歌

avatar
i*a
6
先抢个沙发,谢谢贴了这么多神韵内涵的作品~:)
作品呆会认真回复~

black

【在 h***a 的大作中提到】
: 这是我第一次在美国画的国画。到了美国手痒,没有国画纸,没有墨。只有一只写字的
: 烂毛笔.有一次差一点扯厕所纸来画。这幅画是我用paper towel 画的。墨是用black
: ink。
: 镜框是我才自己作的。

avatar
h*a
7
能不能给个例子什么时候Singleton需要被extend?
为什么你说enum的实现是痛苦的开始?具体说说?这应该现在Core Java最被recommend
的实现了吧?

【在 z****e 的大作中提到】
: 看到其它版面有人说这个pattern
: 单独拿出来说说我的两分钱
: 就我个人而言,我觉得这个pattern可以说是最简单
: 但是也可以说是最难的一个
: 因为陷阱太多,可松可紧,牵涉面很广,不少还是冷僻的东西
: 大概数了数
: 应该有8种方式
: 一个一个说
: 第一种,static instace = new Instance();
: 这种其实也是最常用的方式,eclipse上可以点击实现

avatar
e*t
8
哈哈哈

【在 w****F 的大作中提到】
: 汪峰怎么能和信比。。信的摇滚音色在当代华语世界里没人能比得上了。。不要说
: still loving you或者always了,汪峰大概连《死了都要爱》都唱不好,他的唱法基本
: 就是老狼那种加上一些高音罢了。

avatar
h*a
9
你的美术评论是一流的。【 在 iyiya (伊伊~为伊书) 的大作中提到: 】
avatar
z*e
10
enum还好
不过enum不能extend也不能被extend
所以代码重用就受到限制
前两种不难
第三种才是最可怕的
第三种不仅涉及多线程还扯到jit的优化
这是痛苦的所在

recommend

【在 h*****a 的大作中提到】
: 能不能给个例子什么时候Singleton需要被extend?
: 为什么你说enum的实现是痛苦的开始?具体说说?这应该现在Core Java最被recommend
: 的实现了吧?

avatar
g*g
11
这张专辑我还真试听过。感觉那那都不靠,我个人很不喜欢

【在 s******l 的大作中提到】
: 在线试听
: http://www.xiami.com/album/356069
: 语种 国语
: 唱片公司 艾迴唱片
: 发行时间 2009年11月
: 转自猫扑
: http://ent.mop.com/music/3089102.shtml
: 又是13个月,信推出了新专辑《趁我》。如果还把信跟信乐团搅和在一起,似乎有点对
: 不起信,毕竟发行了四张个人专辑(其中一张是翻唱专辑),数量上已经与乐团持平,还
: 获得过金曲奖最佳男歌手的提名,音乐性也得到了肯定。将其称为定义为一个优秀男歌

avatar
i*a
12
倒。。。汗。。。狂擦汗~:)

【在 h***a 的大作中提到】
: 你的美术评论是一流的。【 在 iyiya (伊伊~为伊书) 的大作中提到: 】
avatar
l*s
13
double check is very rudimentary idiom for multi-threading programming.
avatar
h*a
14
我看你以前写得挺好的。

【在 i***a 的大作中提到】
: 倒。。。汗。。。狂擦汗~:)
avatar
g*g
15
在spring framework里这个还挺常见的,spring提供了一些缺省的实现。你可以写自己
的bean去替代这些实现,可以完全自己写,只实现接口。也可以继承缺省实现扩展。这
些实现大多当singleton用。
spring security里这样的例子就很多。

recommend

【在 h*****a 的大作中提到】
: 能不能给个例子什么时候Singleton需要被extend?
: 为什么你说enum的实现是痛苦的开始?具体说说?这应该现在Core Java最被recommend
: 的实现了吧?

avatar
i*a
16
嗯,咳咳~我有部分fine arts专业背景倒是真的。。。:)
版上写意、工笔、书法的不多,老师的作品我很喜欢。
有meeting...呆会认真回呀~

【在 h***a 的大作中提到】
: 我看你以前写得挺好的。
avatar
z*e
17
double check  不是出问题的地方
是byte code
总之在这里不能用double check
多线程本身没有问题,但是这里要结合多线程来理解为什么会错

【在 l*********s 的大作中提到】
: double check is very rudimentary idiom for multi-threading programming.
avatar
h*a
18
感谢你组织的一系列艺术活动,丰富并活跃了版面,你辛苦了。

【在 i***a 的大作中提到】
: 嗯,咳咳~我有部分fine arts专业背景倒是真的。。。:)
: 版上写意、工笔、书法的不多,老师的作品我很喜欢。
: 有meeting...呆会认真回呀~

avatar
F*n
19
用volatile field double check就没问题
多少年前的讨论了

【在 z****e 的大作中提到】
: double check  不是出问题的地方
: 是byte code
: 总之在这里不能用double check
: 多线程本身没有问题,但是这里要结合多线程来理解为什么会错

avatar
z*e
20
用volatile可以不用double check了
5.0的新版本修正了这个bug

【在 F****n 的大作中提到】
: 用volatile field double check就没问题
: 多少年前的讨论了

avatar
F*n
21
你都没明白为啥要double check 吧
是**可以**不用double check,
double check 是用来避免不必要的读锁

【在 z****e 的大作中提到】
: 用volatile可以不用double check了
: 5.0的新版本修正了这个bug

avatar
c*e
22
俺做jave ee的,很少做core java里这些高级的东东。所知的singleton只是那种在
constructor里面重新new 一个。

【在 z****e 的大作中提到】
: 看到其它版面有人说这个pattern
: 单独拿出来说说我的两分钱
: 就我个人而言,我觉得这个pattern可以说是最简单
: 但是也可以说是最难的一个
: 因为陷阱太多,可松可紧,牵涉面很广,不少还是冷僻的东西
: 大概数了数
: 应该有8种方式
: 一个一个说
: 第一种,static instace = new Instance();
: 这种其实也是最常用的方式,eclipse上可以点击实现

avatar
z*e
23
问题是那样的话double check压根不顶用
直接回到single check上去了
最终解决问题靠得是volatile
而不是几重check
换句话说,只要不加volatile
double check在这里就是错误的
而加了volatile
直接single check就好了

【在 F****n 的大作中提到】
: 你都没明白为啥要double check 吧
: 是**可以**不用double check,
: double check 是用来避免不必要的读锁

avatar
z*e
24
锁本身没有要求说一定要在下一个语句之前释放
所以如果return的话,又会从double check回到single check
同样的问题,所以无论多少重锁,都不能保证没有问题
所以只能依赖volatile来解决

【在 F****n 的大作中提到】
: 你都没明白为啥要double check 吧
: 是**可以**不用double check,
: double check 是用来避免不必要的读锁

avatar
r*s
25
你前一半话是对的,
before1.5就是double也没用,
后一半你理解错了,
1.5+ java 还是要double check,
but using volatile fixes it.

【在 z****e 的大作中提到】
: 问题是那样的话double check压根不顶用
: 直接回到single check上去了
: 最终解决问题靠得是volatile
: 而不是几重check
: 换句话说,只要不加volatile
: double check在这里就是错误的
: 而加了volatile
: 直接single check就好了

avatar
M*r
26
zhaoce 同学很能说,但是在水深的地方就说不清楚了。建议回帖前先 do some
research.

【在 z****e 的大作中提到】
: 问题是那样的话double check压根不顶用
: 直接回到single check上去了
: 最终解决问题靠得是volatile
: 而不是几重check
: 换句话说,只要不加volatile
: double check在这里就是错误的
: 而加了volatile
: 直接single check就好了

avatar
F*n
27
尽瞎说
我觉得你这样去湾区堪忧啊

【在 z****e 的大作中提到】
: 锁本身没有要求说一定要在下一个语句之前释放
: 所以如果return的话,又会从double check回到single check
: 同样的问题,所以无论多少重锁,都不能保证没有问题
: 所以只能依赖volatile来解决

avatar
M*r
28
Double check is not required, but nice to have. Foxman's answer is good.

【在 r*****s 的大作中提到】
: 你前一半话是对的,
: before1.5就是double也没用,
: 后一半你理解错了,
: 1.5+ java 还是要double check,
: but using volatile fixes it.

avatar
r*s
29
能说还是要鼓励的嘛,
这是我们老中Engineer的弱项。

【在 M***r 的大作中提到】
: zhaoce 同学很能说,但是在水深的地方就说不清楚了。建议回帖前先 do some
: research.

avatar
r*s
30
写出来看看,
我都没搞不清你们是光说double checked locking还是singleton

【在 M***r 的大作中提到】
: Double check is not required, but nice to have. Foxman's answer is good.
avatar
z*e
31
我喜欢你的前半句话,哈哈
只不过那样的话,就有可能不是singleton了
而是multiton了,对于大多数情况来说,一则不会出现multiton
二则就算出现,数量也不会很多,所以对于现实不会有太严重的影响
只要不存state就好了,过一下,自然就被gc掉了

【在 M***r 的大作中提到】
: Double check is not required, but nice to have. Foxman's answer is good.
avatar
z*e
32
木有瞎说哦
基本上是原文翻译过来的

【在 F****n 的大作中提到】
: 尽瞎说
: 我觉得你这样去湾区堪忧啊

avatar
z*e
33
第二个check只是为了防止其它的thread提前init一个instance出来
或者说防止其它threads init几个instances出来
只是这种情况毫无必要,灰常subtle
当然非常在乎singleton的话,可以多check一下

【在 r*****s 的大作中提到】
: 写出来看看,
: 我都没搞不清你们是光说double checked locking还是singleton

avatar
M*r
34
The first check is nice to have; the second check (inside sync) is a must.
got it?
if (instance == null) {
synchronized (mylock) {
if (instance == null) {
// initialize instance here
}
}
}

【在 z****e 的大作中提到】
: 第二个check只是为了防止其它的thread提前init一个instance出来
: 或者说防止其它threads init几个instances出来
: 只是这种情况毫无必要,灰常subtle
: 当然非常在乎singleton的话,可以多check一下

avatar
z*e
35
no
你这样会有严重的并发瓶颈
你再想想我说的

【在 M***r 的大作中提到】
: The first check is nice to have; the second check (inside sync) is a must.
: got it?
: if (instance == null) {
: synchronized (mylock) {
: if (instance == null) {
: // initialize instance here
: }
: }
: }

avatar
z*e
36
你把first check去掉之后
就违背了singleton的本意
其本意是节省内存,但是不能出现synchronized的并发瓶颈
要不然直接synchronized方法就好了
不能为了优化一个性能牺牲另外一个性能
保留第一个,就保证了在大并发的时候,不会出现拥堵
第二个可加可不加,多一点instances死不了

【在 M***r 的大作中提到】
: The first check is nice to have; the second check (inside sync) is a must.
: got it?
: if (instance == null) {
: synchronized (mylock) {
: if (instance == null) {
: // initialize instance here
: }
: }
: }

avatar
M*r
37
我前半句其实是在夸他。

【在 r*****s 的大作中提到】
: 能说还是要鼓励的嘛,
: 这是我们老中Engineer的弱项。

avatar
l*s
38
re

【在 F****n 的大作中提到】
: 你都没明白为啥要double check 吧
: 是**可以**不用double check,
: double check 是用来避免不必要的读锁

avatar
l*s
39
我怎么觉得正相反,能瞎说的才会钱途无量啊

【在 F****n 的大作中提到】
: 尽瞎说
: 我觉得你这样去湾区堪忧啊

avatar
g*e
40
第二个不加那还叫啥singleton?

must.

【在 z****e 的大作中提到】
: 你把first check去掉之后
: 就违背了singleton的本意
: 其本意是节省内存,但是不能出现synchronized的并发瓶颈
: 要不然直接synchronized方法就好了
: 不能为了优化一个性能牺牲另外一个性能
: 保留第一个,就保证了在大并发的时候,不会出现拥堵
: 第二个可加可不加,多一点instances死不了

avatar
z*e
41
这倒是真的哈
不过你先把后面回文看完
我觉得某人没有认真想我在说什么
其实那种情况我一开始就排除了
压根都不打算讨论,那么明显的缺陷
说了有啥意义

【在 l*********s 的大作中提到】
: 我怎么觉得正相反,能瞎说的才会钱途无量啊
avatar
M*r
42
你现在是本末倒置。真为你公司的前景担忧。 :)
Do thing right, then make it better.
Just remind you that the second check within sync is to guard singleton,
while the first is to improve scalability.

【在 z****e 的大作中提到】
: 你把first check去掉之后
: 就违背了singleton的本意
: 其本意是节省内存,但是不能出现synchronized的并发瓶颈
: 要不然直接synchronized方法就好了
: 不能为了优化一个性能牺牲另外一个性能
: 保留第一个,就保证了在大并发的时候,不会出现拥堵
: 第二个可加可不加,多一点instances死不了

avatar
z*e
43
对啊,所以说是multiton啊
只不过这个可能性灰常小罢了
比起第一个不加出现瓶颈的情况来说
当然还不如用第二种
不是singleton就不是咯
没啥大不了的
这其实有个优先级排序
第一不能防止出错,所以必需加volatile
第二要保证优化内存使用同时不能牺牲其它性能
synchronized必需慎重使用,否则情愿不用singleton
第三才是singleton
显然第二个check优先级是最低的

【在 g**e 的大作中提到】
: 第二个不加那还叫啥singleton?
:
: must.

avatar
z*e
44
那要看你认为singleton是right还是wrong了
我觉得跟并发瓶颈比起来,显然singleton是优先级低的考虑

【在 M***r 的大作中提到】
: 你现在是本末倒置。真为你公司的前景担忧。 :)
: Do thing right, then make it better.
: Just remind you that the second check within sync is to guard singleton,
: while the first is to improve scalability.

avatar
g*e
45
按你这么干,大并发的情况下,直接OOM
没什么原因别用singleton,一定要用的情况下就要用好,不然不如不用。直接spring
inject一个

【在 z****e 的大作中提到】
: 对啊,所以说是multiton啊
: 只不过这个可能性灰常小罢了
: 比起第一个不加出现瓶颈的情况来说
: 当然还不如用第二种
: 不是singleton就不是咯
: 没啥大不了的
: 这其实有个优先级排序
: 第一不能防止出错,所以必需加volatile
: 第二要保证优化内存使用同时不能牺牲其它性能
: synchronized必需慎重使用,否则情愿不用singleton

avatar
M*r
46
那也不能满嘴炮火车。可以说无用的,但不能是错的。否则钱途真是没量。毕竟这世界
能人太多了。很容易被揭穿。

【在 l*********s 的大作中提到】
: 我怎么觉得正相反,能瞎说的才会钱途无量啊
avatar
z*e
47
这种情况的确是不怎么用,因为5.0以后有enum了
多数时候就是让spring inject一个

spring

【在 g**e 的大作中提到】
: 按你这么干,大并发的情况下,直接OOM
: 没什么原因别用singleton,一定要用的情况下就要用好,不然不如不用。直接spring
: inject一个

avatar
l*s
48
搞定老板才是重点,这个和技术水品关系不大。

【在 M***r 的大作中提到】
: 那也不能满嘴炮火车。可以说无用的,但不能是错的。否则钱途真是没量。毕竟这世界
: 能人太多了。很容易被揭穿。

avatar
z*e
49
其实我开始说的是为什么要加volatile
你在说为什么要用double check

【在 M***r 的大作中提到】
: 那也不能满嘴炮火车。可以说无用的,但不能是错的。否则钱途真是没量。毕竟这世界
: 能人太多了。很容易被揭穿。

avatar
a*e
50
漏了一种static factory的

【在 z****e 的大作中提到】
: 看到其它版面有人说这个pattern
: 单独拿出来说说我的两分钱
: 就我个人而言,我觉得这个pattern可以说是最简单
: 但是也可以说是最难的一个
: 因为陷阱太多,可松可紧,牵涉面很广,不少还是冷僻的东西
: 大概数了数
: 应该有8种方式
: 一个一个说
: 第一种,static instace = new Instance();
: 这种其实也是最常用的方式,eclipse上可以点击实现

avatar
g*e
51
那个其实是enum之外最好的

【在 a**e 的大作中提到】
: 漏了一种static factory的
avatar
z*e
52
没太看明白,之后放狗搜了一下
原来如此
其实这是我说的第一种
public访问变量的形式一般不主张使用哈
所以其实要说遗漏的话
应该是漏掉了public访问的那种
最简单想到的那种

【在 a**e 的大作中提到】
: 漏了一种static factory的
avatar
z*e
53
补充一个真正难的
用final来替换volatile
public class FinalWrapper {
public final T value;
public FinalWrapper(T value) {
this.value = value;
}
}
public class Foo {
private FinalWrapper helperWrapper = null;
public Helper getHelper() {
FinalWrapper wrapper = helperWrapper;
if (wrapper == null) {
synchronized(this) {
if (helperWrapper == null) {
helperWrapper = new FinalWrapper(new Helper());
}
wrapper = helperWrapper;
}
}
return wrapper.value;
}
}
所以大概有10种写法
avatar
g*e
54
显然跟你说的第一种不同。这个是lazy init的

【在 z****e 的大作中提到】
: 没太看明白,之后放狗搜了一下
: 原来如此
: 其实这是我说的第一种
: public访问变量的形式一般不主张使用哈
: 所以其实要说遗漏的话
: 应该是漏掉了public访问的那种
: 最简单想到的那种

avatar
s*e
55
Basically there are three ways to create singleton: lazy init, eager init
and holder pattern.
Both of eager init and holder pattern depend on JVM class loading process to
guarantee the singleton. The holder pattern was introduced in trying to
avoid
creating a singleton unnecessarily in the case of the eager
initialization.
For lazy init, no matter using doubly checked lock or not, you can both
create a singleton if you use it correctly. The reason trying to introduce
doubly checked lock was to reduce the lock scope and in turn reduce the time
needed when a singleton is accessed or created. As pointed out by somebody,
before 1.5, JMM has a bug related to the memory barrier, which caused doubly
checked locking didn't work even you put the volatile keyword. The bug was
fixed in 1.5+.
Today, singleton pattern is thought to be hard to test and need to be
avoided. Like it or not, it is fully up to you. But it does have some issues
mentioned by Joshua in his "Effective Java". Since serialization or clone
tends to skip the constructor, a regular java class will have a difficult
time to
guarantee the singleton when those mechanisms are used. Enum in java is
guaranteed to be singleton no matter what happens. That is why he
recommends enum for creating a singleton. But in my opinion, in most case,
you
might not need to do that. I haven't experienced a situation that I have to
guarantee the singleton when serialization or clone is involved...
avatar
g*g
56
Double check is for efficiency, otherwise you have to put
synchronize(this) before check.

【在 z****e 的大作中提到】
: 问题是那样的话double check压根不顶用
: 直接回到single check上去了
: 最终解决问题靠得是volatile
: 而不是几重check
: 换句话说,只要不加volatile
: double check在这里就是错误的
: 而加了volatile
: 直接single check就好了

avatar
r*s
57
所以说,
你们都跑题了,
拗吧你就。
赶紧来湾区,
湾区老印们就靠你搞定了,
呵呵。

【在 z****e 的大作中提到】
: 第二个check只是为了防止其它的thread提前init一个instance出来
: 或者说防止其它threads init几个instances出来
: 只是这种情况毫无必要,灰常subtle
: 当然非常在乎singleton的话,可以多check一下

avatar
r*s
58
有点回字的四种写法的意思了,
这里有:
http://en.wikipedia.org/wiki/Double-checked_locking

【在 z****e 的大作中提到】
: 补充一个真正难的
: 用final来替换volatile
: public class FinalWrapper {
: public final T value;
: public FinalWrapper(T value) {
: this.value = value;
: }
: }
: public class Foo {
: private FinalWrapper helperWrapper = null;

avatar
z*e
59

所以水很深
而且这个链接里面没有给出真正的原因和解释
这个优化其实是double check的优化+final来搞定锁机制
double check的优化可以单独拿出来说

【在 r*****s 的大作中提到】
: 有点回字的四种写法的意思了,
: 这里有:
: http://en.wikipedia.org/wiki/Double-checked_locking

avatar
z*e
60
关于double check,有一个优化版
这个优化版的问题可不是那么简单的
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) {
Singleton inst = instance;
if (inst == null)
{
synchronized(Singleton.class) {
inst = new Singleton();
}
instance = inst;
}
}
}
return instance;
}

【在 r*****s 的大作中提到】
: 所以说,
: 你们都跑题了,
: 拗吧你就。
: 赶紧来湾区,
: 湾区老印们就靠你搞定了,
: 呵呵。

avatar
h*a
61
看了这么多讨论,只能说各种方法都有自己适用的场合。
1)某些情况下产生了多个instance有没有问题,有多大问题
2)如果不需要一个instance的话是不是就不能创建(lazy),如果eager的创建了会不
会有很大的影响
3)Singleton的type有没有被继承的需要
这几个需求不搞清楚,讨论哪种方法更好是没意义的。用enum实现无非是因为简单,而
且JVM层面上guarantee了instance唯一性,维护成本下降。但如果在需要lazy init或
者继承的场合就不见的适用了。
avatar
g*g
62
If you are writing a spring app or guice app, it's no brainer which way you
should go. Otherwise you choose the way you most comfortable with.
I don't like a supposed singleton not singleton in marginal scenario. An OK
case today may be a nightmare case when getting extended, and the maintainer
won't necessarily know the limitation of your "singleton".

【在 h*****a 的大作中提到】
: 看了这么多讨论,只能说各种方法都有自己适用的场合。
: 1)某些情况下产生了多个instance有没有问题,有多大问题
: 2)如果不需要一个instance的话是不是就不能创建(lazy),如果eager的创建了会不
: 会有很大的影响
: 3)Singleton的type有没有被继承的需要
: 这几个需求不搞清楚,讨论哪种方法更好是没意义的。用enum实现无非是因为简单,而
: 且JVM层面上guarantee了instance唯一性,维护成本下降。但如果在需要lazy init或
: 者继承的场合就不见的适用了。

avatar
z*e
63
我看了一下effective java,确认了一下你说的static factory是不是我想的那个
貌似你说得不对吧?
static factory不是lazy init的吧
在加载class之后,这个对象就被实例化了

【在 g**e 的大作中提到】
: 显然跟你说的第一种不同。这个是lazy init的
avatar
z*e
64
zkss
为啥这个是lazy init的

【在 g**e 的大作中提到】
: 显然跟你说的第一种不同。这个是lazy init的
avatar
z*e
65
但是现实中的确会用到clone方法
我倒是觉得clone+非enum的singleton配合还是挺好的
可以动态实现有限个对象
enum限制得太死了

you
OK
maintainer

【在 g*****g 的大作中提到】
: If you are writing a spring app or guice app, it's no brainer which way you
: should go. Otherwise you choose the way you most comfortable with.
: I don't like a supposed singleton not singleton in marginal scenario. An OK
: case today may be a nightmare case when getting extended, and the maintainer
: won't necessarily know the limitation of your "singleton".

avatar
z*e
68
问你跟其它几个牛人一个问题
这里锁的是(this)之类的对象么?还是(MyClass.class)?还是两个都可以?
我看你们这里都用了this或者是mylock,小写开头,我假设就是对象了
但我觉得是后者才对,也就是synchronized(MyClass.class)才对
如果锁的是this的话,那其它的MyClass类一样可以实例化很多对象出来
这里可能不会出现争抢的情况,锁this是没有太大意义的
除非assume外面这个MyClass已经是singleton了,那这个显然是有问题的
要把整个Class在方法区中锁住才行
我隐隐约约觉得不存在有锁this的singleton实现

【在 M***r 的大作中提到】
: The first check is nice to have; the second check (inside sync) is a must.
: got it?
: if (instance == null) {
: synchronized (mylock) {
: if (instance == null) {
: // initialize instance here
: }
: }
: }

avatar
s*r
69
spring里面的singleton和core java的singlton有区别,后者是保证JVM里面只有一个
instance,spring只能保证一个ApplicationContext里面只有一个instance
avatar
c*e
70
这种东西,oracle要解决掉才行,不然象现在这样,大家都觉得很含糊。

【在 s*****r 的大作中提到】
: spring里面的singleton和core java的singlton有区别,后者是保证JVM里面只有一个
: instance,spring只能保证一个ApplicationContext里面只有一个instance

avatar
F*X
71
singleton pattern 和 servlet 是不是很相似?都共用instance?
avatar
z*e
72
对于线程来说是这样,但是这两个是不同的东西
大多数servlet都是singleton,但是容器可以创建多个instance

【在 F*******X 的大作中提到】
: singleton pattern 和 servlet 是不是很相似?都共用instance?
avatar
S*C
73
严格来说,singleton的scope是class loader,而不是JVM,
同一个JVM底下可以有多个class loader.

【在 s*****r 的大作中提到】
: spring里面的singleton和core java的singlton有区别,后者是保证JVM里面只有一个
: instance,spring只能保证一个ApplicationContext里面只有一个instance

avatar
b*t
74
Yes.
Each class is identified in JVM by the combination of class name, package
name and its class loader.
Same class loaded by different class loaders is regarded to be different
classes; Even if for system loader, you can still load the class already
loaded by the system class loader, from a seperate URL.

【在 S**********C 的大作中提到】
: 严格来说,singleton的scope是class loader,而不是JVM,
: 同一个JVM底下可以有多个class loader.

avatar
G*W
75
关于double check,是不是风向又变了,我没有看见?记得java currency in
practice是写到java1.6,就在书中,写singleton的时候,是说用volatile的double
lock check就可以了,而且必须是java1.5 (or1.6??)之后volatile才有用,原因
楼上说过了,什么JIT等等等等深水区;
后来再一篇文章里面讲到,enum拿来做singleton很不错,因为it is static, final
be default, and lazy init.
不过我从来没有考虑过extend enum。如果还有这个考虑,那。。。呵呵,我水没有那
么深
avatar
x*o
76
看你们讨论水就太深了,我只记着ENUM和FACTORY写法,其他的自认没那个本事研究透彻
觉得还是找策牛,职场不是看技术多牛,是看嘴巴多能说
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。