A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© muma 中级黑马   /  2014-4-4 09:30  /  1331 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

多程序读取一个配置文件时,建议配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。
Runtime()方法就是单例设计模式进行设计的。
如何保证对象唯一性呢?

11 个回复

倒序浏览
想要保证对象唯一。
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三部怎么用代码体现:
1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法可以获取到该对象。
比如单例模式代码:
  1. class Single
  2. {
  3.         private int Num;

  4.         private Single(){}

  5.         private static Single s = new Single();

  6.         public static  Single getInstance()
  7.         {
  8.                 return s;
  9.         }
  10.         public void setNum(int Num)
  11.         {
  12.                 this.Num = Num;
  13.         }
  14.         public int getNum()
  15.         {
  16.                 return Num;
  17.         }
  18. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
懒汉式中为什么要用同步和双判断呢
回复 使用道具 举报

  1. <P>懒汉式1:</P>
  2. <P>class Single
  3. {
  4.    private Single(){}
  5.    private Single s = null;
  6.    public static Single getInstance()
  7.    {</P>
  8. <P>         if(s == null)</P>
  9. <P>         //cpu处理程序的特点时,是跳转的,当if(s == null)执行完了之后,就可能去执行其他的程序了,当又有一个对象调用</P>
  10. <P>        //getInstance()时,s依然为空,就能够通过if,就会出现创建了两个Single对象。</P>
  11. <P>         s = new Single(); </P>
  12. <P>         return s;
  13.    }
  14. }</P>
  15. <P> </P>
  16. <P>懒汉式2:</P>
  17. <P>class Single
  18. {
  19.    private Single(){}
  20.    private Single s = null;
  21.    public static Single getInstance()
  22.    {</P>
  23. <P>         if(s == null)</P>
  24. <P>         {//这里也会出项上述问题,但是下面加了一个“锁”</P>
  25. <P>              synchronizaed(Single.class)//只能够进入一个调用进入</P>
  26. <P>             {</P>
  27. <P>                 if(s ==null)//其他调用再进来则s就不为空了,就不会出现创建多个对象。</P>
  28. <P>                 {</P>
  29. <P>                       s = new Single(); </P>
  30. <P>                 }</P>
  31. <P>              }</P>
  32. <P>         }</P>
  33. <P>         return s;
  34.    }
  35. }</P>
  36. <P> </P>
复制代码

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
muma 发表于 2014-4-4 11:00
懒汉式中为什么要用同步和双判断呢

因为懒汉式在多线程时会产生安全问题
而解决这个问题的方法可以用同步代码块或者同步函数
但是效率会降低因为每一个线程都要去判断
解决这个问题的方法就是双重否定加同步去判断可以减少同步判断的次数提高效率

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
759345779 发表于 2014-4-4 09:45
想要保证对象唯一。
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程 ...

求教个问题  
就是用通过继承Thread类,通过单例模式解决共享数据问题 比如你设置一个i,让两个线程递增到100,要求就是int不能定义成static 必须是对象成员
回复 使用道具 举报
caijunsong 发表于 2014-4-4 12:44
求教个问题  
就是用通过继承Thread类,通过单例模式解决共享数据问题 比如你设置一个i,让两个线程递增 ...

你的意思是两个线程共同操作一个变量吗?如果是的话,你可以实现Runnable接口比较好一些,就像卖票那个经典的例子,票源是一个变量。
回复 使用道具 举报
759345779 发表于 2014-4-4 13:43
你的意思是两个线程共同操作一个变量吗?如果是的话,你可以实现Runnable接口比较好一些,就像卖票那个经 ...

这不是我想要的  
回复 使用道具 举报

还不太懂你的意思,能再详细点吗?
回复 使用道具 举报
哥们,我来贴上。我以前做的时候的代码。希望能帮的上你。这里是使用的threadlocal. 有详细的文字说明和备注.
  1. //当数据多的时候我们使用对象进行封装
  2. /**
  3. * 总结:
  4. *  我们这里其实是把封装多个数据的类做成了单例,然后在这个类的内部封装了一个ThreadLocal,
  5. *  在获取本类实例的静态方法中,首先是从当前线程获取是否有本类的实例存在,如果存在就返回,
  6. *  如果没有存在,就创建,然后把创建的本类的实例设置到当前的线程中。然后返回这个对象。使用
  7. *  这个样的封装。避免了保证了封装数据的对象在线程中的唯一性。保证了每个模块是从同一个对象
  8. *  身上获取的数据。
  9. */
  10. class ThreadScopeData{
  11.         //我们先把这个类给做成单例的
  12.         private ThreadScopeData(){}
  13.         //别人不能创建这个类的实例对象但是可以通过我们提供的静态方法来获取这个类的实例对象
  14.         public static ThreadScopeData getThreadInstance(){
  15.                 //饥汉模式存在一种线程安全的问题。就是说A线程调用了这个语句,要获取这个类的实例,但是
  16.                 //这个类的实例不存在,所以它就需要创建,还没有给这个引用赋值,这个时候B线程也进来了。
  17.                 //它判断对象也没有所以它也创建了。所以在内存里面就出现了两个这个类的实例。
  18.                 //这个时候了。我们就需要把这个方法做成互斥的。
  19. //                return instance; //饱汉模式是直接返回创建好的实例对象
  20.                 //我们在调用这个方法的时候就直接去当前线程上取数据
  21.                 //取到的是于当前线程相关的实例对象
  22.                 ThreadScopeData instance=myThreadData.get();  //获取与本线程相关的实例对象
  23.                 //我们把当前这个类的实例对象,因为这个类是单例的所以只能有一个实例对象,我们把它给添加到
  24.                 //到当前线程上去了。就意味着在当前线程中只会有一个实例对象的存在。这样在当前线程上的所有模块
  25.                 //拿到的数据都是同一份,因为我们的这个方法最开始的语句是从当前线程中获取实例对象,如果对象
  26.                 //存在就返回对象如果不存在就创建对象然后设置到线程中。A线程在没有获取到实例对象创建的时候,
  27.                 //还没有赋值。B线程也没有获取到。它也创建。这个时候我们的方法是可以不用互斥的。因为它们是从不
  28.                 //同的线程中获取的实例对象。A线程不会影响到B线程。B线程也不会影响到A线程。
  29.                 if(instance==null){  //在调用这个方法的时候,如果对象存在就直接返回
  30.                         //如果对象不存在就创建这个对象然后返回这个对象的实例
  31.                         instance=new ThreadScopeData();
  32.                         //如果对象存在就直接返回如果不存在就创建这个对象给设置到当前线程上去。
  33.                         myThreadData.set(instance);
  34.                 }
  35.                 return instance;
  36.         }
  37.         //我们这么来做,我们把当前创建的对象的实例给设置到当前的线程中
  38.         private static ThreadLocal<ThreadScopeData> myThreadData=new ThreadLocal<ThreadScopeData>();
  39.        
  40.         //顺便演示一下单例中的两种模式
  41.         //这是饱汉模式:对象直接创建创建好的。它是随着类的加载而加载
  42. //        private static MyThreadLocalScopeData instance=new MyThreadLocalScopeData();
  43.         //这里是饥汉模式:对象引用先创建但是赋的是空值
  44. //        private static MyThreadLocalScopeData instance=null;
  45.        
  46.         private String name;
  47.         private int age;
  48.         public String getName() {
  49.                 return name;
  50.         }
  51.         public void setName(String name) {
  52.                 this.name = name;
  53.         }
  54.         public int getAge() {
  55.                 return age;
  56.         }
  57.         public void setAge(int age) {
  58.                 this.age = age;
  59.         }
  60. }
复制代码
回复 使用道具 举报
syusikoku 发表于 2014-4-7 12:52
哥们,我来贴上。我以前做的时候的代码。希望能帮的上你。这里是使用的threadlocal. 有详细的文字说明和备 ...

这个我看张老师 的ThreadLocal后 本来我也想 毕老师说的在Thread共享数据用单例模式 可能就是这个吧
不过还是谢谢你  要是能进去再问问老师爱吧   
回复 使用道具 举报
这个要用到单例模式:饿汉式、懒汉式。
饿汉式:public Single{
           private static Single s=new Single();//先初始化一对象
           private Single() {}//私有构造函数
           public static Single getInstance() {//通过函数获取对象
               return s;
           }
}
懒汉式:public Single{
           private static Single = null//先声明一对象
           private Single() {}//私有构造函数
           public static Single getInstance() {//通过函数获取对象
               if(s==null) s=new Single();//如果空,则初始化一对象
               return s;
           }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马