精华帖 (0) :: 良好帖 (3) :: 新手帖 (2) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2011-06-07
star022 写道 public class Singleton {
private static final Singleton INSTANCE = new Singleton(); private Singleton() { } public static Singleton getInstance() { return INSTANCE; } } 如果不涉及到共享资源的访问,单例为何还需要枷锁? public class Singleton { private static Singleton instance = null; public synchronized static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 如果采用按需创建单例模型就需要同步 防止多线程创建多个对象 |
|
返回顶楼 | |
发表时间:2011-06-07
star022 写道 public class Singleton {
private static final Singleton INSTANCE = new Singleton(); private Singleton() { } public static Singleton getInstance() { return INSTANCE; } } 如果不涉及到共享资源的访问,单例为何还需要枷锁? 呵呵 ! 这是饿汉模式,这个是没有问题的。 但是懒汉模式是非常需要的,而且还存在很多问题。 如: public class Singleton { private static final Singleton INSTANCE; private Singleton() { } public static Singleton getInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } } 这样的代码多线程下当然存在问题。 关于单例的几种形式请看: http://cantellow.iteye.com/blog/838473 |
|
返回顶楼 | |
发表时间:2011-06-07
Mic_X 写道 xfei6868 写道 AlwenS 写道 也有一种可能是楼主没理解透他们的意思。
单例容易造成应用热点,这点不用怀疑吧? 如果这个热点(单例)还带可更改的状态,那么对状态的访问势必引入并发控制。 一个需要并发控制的热点,因其访问竞争问题,大多数情况下会成为性能杀手(热点阻塞)。 加上他们思维跳跃太快,于是就变成单例 - > 阻塞了。 呵呵,只是想说不要把别人想得太傻,一些人能混得下来必然有他的亮点。 看了您的回复,还是没看到单例跟阻塞有什么关系. 你拉扯了一大堆的关联,可能行. 说到底还是看这个对象是可变的还是非可变的。 单例只是一定范围内只有一个对象,而不用单例照样存在一个对象被多线程使用的情况,是可变对象话照样是需要考虑线程安全的。 AlwenS说的没错,如果是可变对象,在改变状态的方法上会引入并发控制,通常是synchronized方法,因为只有一个对象,同时访问synchronized方法时当然会阻塞。 如果是不可变对象,那就不需要考虑并发控制了,也不会引起性能问题。 可变对象在多线程的场景下使用的话,一样要对其进行做线程安全处理啊。 一个对象在多线程使用的时候是要考虑的是这个对象是不是处于多线程环境中,如果是就要考虑线程安全。 这跟单例真的没关系,从外部拿到一个对象的话,你能管他是不是单例吗? |
|
返回顶楼 | |
发表时间:2011-06-07
LZ,沟通最重要...你这样在网上说,万一被末位公司有心人给看到 联想到了你,就悲催了。有不同的意见可以提出来嘛,你不说,人家怎么知道你的想法,也许,好的意见,想法就这样默默的,默默的,默没了...
|
|
返回顶楼 | |
发表时间:2011-06-07
zenghuiss 写道 LZ,沟通最重要...你这样在网上说,万一被末位公司有心人给看到 联想到了你,就悲催了。有不同的意见可以提出来嘛,你不说,人家怎么知道你的想法,也许,好的意见,想法就这样默默的,默默的,默没了...
嘿嘿! 喜欢你的回复方式。 其实在这说的时候掺杂的感情比较多,比如里面说了其他的一些东西。 还有沟通是很重要,盲目出头是吃亏过不少,最近在明哲保身。 有人主动压迫到我这的时候,不对的地方我会尽我知道的知识去争,往往能保住自己,当然给人也没留下好印象。 但是,我奇怪的是他们如果没能说服我,知道我是对的话,应该会大刀阔斧的改他的东西啊。 如果我学习或讨论的时候联想到自己的以前做过的东西有大错误的话,我会“偷偷”的都改掉的,然后重构一下,这种感觉很好的。 可能他们是太忙了。 |
|
返回顶楼 | |
发表时间:2011-06-07
首先,lz,你的理解没错。对一个对象的操作是否需要同步,并不取决于他是否是单例,而是取决于是否会被多个线程访问。
但是,lz,只听你的介绍,不清楚他们几个的上下文,以及讨论涉及到的具体代码,很难说他们是不是真的什么都不懂。比如,我就倒现在也搞不清overhide和override的中文,到底哪个是哪个,但IMHO,这似乎不影响我对这两个概念的掌握和应用。同样的,很多人,会把buffer和cache的中文说反。但是只要能搞清楚buffer/cache的区别,问题似乎也不是很严重。 |
|
返回顶楼 | |
发表时间:2011-06-07
最后修改:2011-06-07
8)
是阻塞其他线程吗? 别管自己什么身份,哪怕你是一个扫地的,只要你能解决,你就是高人。 反正也是新人,即使说错了,你也不吃亏,相反,一大堆所谓的高手讨论上百度都能搜到的内容,纯属浪费时间。 |
|
返回顶楼 | |
发表时间:2011-06-07
最后修改:2011-06-07
单例类一般用在资源的操作上,资源共享的时候会在很多操作(方法)上加同步锁,那么此时有两个线程都在调用这个类的方法,比如线程1调用A(),线程2调用B(),而A和B都是同步方法,当线程1先过来调A()的时候,线程2此时是需要等待线程1失去锁,换自己进入B。这是锁的机制,是内定的。这么设计的原因:我们可以想象,一个单例类在某个方法上加锁,那么说明这个方法肯定是对共享的资源进行了操作,那么我们不排除,另一个方法(有可能)也会对这个资源进行一些操作。所以,只要某个线程拿到锁之后进入了我的同步方法,那么其他的线程就只能在任何一个同步锁的方法外面等着呢。我想的话,他们说的阻塞是这个意思。
|
|
返回顶楼 | |
发表时间:2011-06-07
xfei6868 写道 AlwenS 写道 xfei6868 写道 AlwenS 写道 也有一种可能是楼主没理解透他们的意思。
单例容易造成应用热点,这点不用怀疑吧? 如果这个热点(单例)还带可更改的状态,那么对状态的访问势必引入并发控制。 一个需要并发控制的热点,因其访问竞争问题,大多数情况下会成为性能杀手(热点阻塞)。 加上他们思维跳跃太快,于是就变成单例 - > 阻塞了。 呵呵,只是想说不要把别人想得太傻,一些人能混得下来必然有他的亮点。 看了您的回复,还是没看到单例跟阻塞有什么关系. 你拉扯了一大堆的关联,可能行. 说到底还是看这个对象是可变的还是非可变的。 单例只是一定范围内只有一个对象,而不用单例照样存在一个对象被多线程使用的情况,是可变对象话照样是需要考虑线程安全的。 你没理解我的意思。 如果你我无法在"单例容易造成热点"这个论点上达成共识,那么其它的就不用多说了。 我是能理解你的意思,但是我不喜欢你“热点”的说法,和“容易”的形容。 我认为的计算机的东西是什么样的就是什么样的,对就是对,错就是错,很简单运行出来。 如果jdk的设计人员,都在应该不会出问题的地方就不这样做,或那样做,能做出来这么多人使用的类库吗? 当然 我觉得自己也有很多东西不懂,需要学习,但是自己不会随意的创造想当然的说法。 比如 他们今天又说了一个不含有任何非局部变量的方法应该加锁的问题,又在想象多线程怎么怎么的运行。 我只能静静的,静静的,默默的实现着别人的空方法,一层层的“框架”,所谓的“解耦”,不断修改接口后的修改,还能怎么样呢? 单例处理不好就是容易造成热点,今天我还碰到了,在单例的getInstance方法前面加上synchronized方法,这样的代码在高压下,成了性能的瓶颈。就像下面这种代码一样。 public synchronized static Object getInstance(){ if(instance==null){ load(); } return instance; } |
|
返回顶楼 | |
发表时间:2011-06-08
单例请消除synchronized
http://www.iteye.com/topic/1047991 |
|
返回顶楼 | |