论坛首页 入门技术论坛

java关于单例模式的一些疑问?

浏览 14973 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-04-22   最后修改:2009-04-22
引用
单例首要的条件就是线程安全,所以不会有线程公享资源的事情,何来资源一说?要是有资源公享的话,那还是单例吗?


是的,但我的理解“共享”是“所有线程共享了进程的资源”,而这里的单例实例就是其中的一部分。

  而“共享”并非“同时使用”吧~ 就像那位兄台说的“厕所”
  所以为了解决“同时使用”带来的问题,就得做好“线程安全”了。
0 请登录后投票
   发表时间:2009-04-23  
构造方法私,是防止在其他类中new对象,但你的属性是static的,所以即使在其他类中new了n个对象,但他们的属性是共享的,所以要考虑安全问题,你可以加个类锁,这样数据就安全了,所以私有的构造方法不是必须的,
1 请登录后投票
   发表时间:2009-04-24  
longrui 写道
chenhua_1984 写道
1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事?

1.私有构造行数是禁止通过实例该类获得对象,如:
new Test().getInstence();

2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。
所以一般使用synchronized关键字将该方法声明成同步方法,如:
public static synchronized Test getInstence


线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。
单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。

0 请登录后投票
   发表时间:2009-04-24  
sunnymoon 写道
longrui 写道
chenhua_1984 写道
1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事?

1.私有构造行数是禁止通过实例该类获得对象,如:
new Test().getInstence();

2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。
所以一般使用synchronized关键字将该方法声明成同步方法,如:
public static synchronized Test getInstence


线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。
单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。


多个线程同时操作一个单例,不就不安全了吗???
0 请登录后投票
   发表时间:2009-04-24  
有人根据创建的时间把单例模式分为懒汉式和饿汉式
懒汉式是指在调用的时候才创建,就像你前面的代码所做的,优点是只有用到了才会占用资源
饿汉式是在初始化就创建了这个对象,优点是预先加载,在调用时省去了创建(还有可能加载配置数据)的时间
0 请登录后投票
   发表时间:2009-04-24  
youthon 写道
有人根据创建的时间把单例模式分为懒汉式和饿汉式
懒汉式是指在调用的时候才创建,就像你前面的代码所做的,优点是只有用到了才会占用资源
饿汉式是在初始化就创建了这个对象,优点是预先加载,在调用时省去了创建(还有可能加载配置数据)的时间

饿汉式:在类加载时static{}.静态块中
0 请登录后投票
   发表时间:2009-04-25  
kulinglei 写道
sunnymoon 写道
longrui 写道
chenhua_1984 写道
1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事?

1.私有构造行数是禁止通过实例该类获得对象,如:
new Test().getInstence();

2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。
所以一般使用synchronized关键字将该方法声明成同步方法,如:
public static synchronized Test getInstence


线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。
单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。


多个线程同时操作一个单例,不就不安全了吗???


no
0 请登录后投票
   发表时间:2009-04-27  
一般Singleton模式通常有几种形式:

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   }
}




第二种形式:

public class Singleton {
  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  if (instance==null)
    instance=new Singleton();
  return instance;   }

}




使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。


1 请登录后投票
   发表时间:2009-04-27  
lkjust08 写道
一般Singleton模式通常有几种形式:

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   }
}




第二种形式:

public class Singleton {
  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  if (instance==null)
    instance=new Singleton();
  return instance;   }

}




使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。



多谢!明白了
0 请登录后投票
   发表时间:2009-04-28   最后修改:2009-04-28
C_J 写道
tangshd 写道
本来不想注册 写道
Constructor的用法 和 static 的用法,如果不熟悉,可以用单例模式来加深对他们的理解。

单例模式的写法有很多吧,最简洁的才是最好的。

一个实例,虽然节约资源,缺点应该也很明显。就好比,厕所小便槽就一个,大家要排队等候。



兄台,您这个比喻好像不对吧..单例又不是单线程!


[b]所有线程都共享一个资源

一个线程共享所有资源[/b]

要是“资源”是马桶,排队的就是“线程”。

兄台为什么认为那位兄台比喻不对呢??

我同意 "所有线程都共享一个资源"这个观点, 我不认可的是 拿到"单例对象"后的其他操作的时候,不应该是排队等待,应该是竞争,当然这个操作是在没有加锁的情况下.
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics