黑马程序员——多线程和单例设计模式
2013-07-23 18:47
204 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------
Java程序员在编写程序时,为了满足某些需求,对特定的需求会有特定的程序编写格式,这就是设计模式。Java中常见的设计模式有23种,比如工厂设计模式,代理设计模式等等。单例设计模式也是常见的设计模式之一,它是用来满足一个类在内存只存在一个对象的需求。
要保证对象唯一要满足以下几点:
1.为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2.为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
以上三点怎么用代码体现呢?
1.将构造函数私有化。
2.在类中创建一个本类对象。
3.提供一个方法可以获取到该对象。
其实对于所有的事物对象,当它需要保证在内存中唯一时,加上以上三步即可。
对于单例设计模式来说,它又分为两种情况,一种是饿汉式,一种是懒汉式。
饿汉式,先初始化对象。如下,Single类一进内存,就已经创建好了对象。
class Single{
privateSingle(){}//私有化构造函数。
privatestatic Single s = new Single();//创建Single对象。
publicstatic Single getInstance(){//提供方法使得外界可以获取该对象。
return s;
}
}
懒汉式,对象是方法被调用时才初始化,也叫做延时加载。Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
class Single{
private static Single s = null;//先不初始化。
private Single(){}
public static Single getInstance(){
if(s==null)//判断s是否为null,是即初始化。
s = new Single();
return s;
}
}
从以上两种方式,我们可以看出懒汉式会比饿汉式对于内存优化方面更有优势,因为它是需要时才加载,减少了对内存的浪费。但是懒汉式延时加载会存在安全问题,当有多线程访问时,如果前一个线程访问到if(s==null)这句代码,判断s为null,然后在执行初始化对象时线程暂时停止了,这时有另一个线程进行if(s==null)的判断,也是为true的,也会执行初始化语句。那么,等到前一个线程继续执行,其实内存中会存在不只一个Single对象。
所以,我们需要对懒汉式进行安全问题处理,可以加同步代码块或者同步函数。从代码可以看出操作共享数据的代码就是if(s==null)和s= new Single()这两句代码。可以将这两句代码放进同步代码块中,即
synchronized(Single.class){//这里要注意使用的锁是该方法所在类的字节码文件对象
if(s==null)
s = new Single(); }
但是这样做了之后,每个线程要继续判断锁,不管s是否已经被初始化了,这样会使得效率变低。为了解决效率低下的问题,可以在同步代码块之前加多一个判断语句,判断s是否已经被初始化,如果已经被初始化了,就可以直接跳过判断锁的语句了。即
if(s==null){
synchronized(Single.class){
if(s==null)
s = new Single();
}
}
return s;
利用双重判断的方式就可以解决效率问题啦。
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------
详细请查看:http://edu.csdn.net
ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------
Java程序员在编写程序时,为了满足某些需求,对特定的需求会有特定的程序编写格式,这就是设计模式。Java中常见的设计模式有23种,比如工厂设计模式,代理设计模式等等。单例设计模式也是常见的设计模式之一,它是用来满足一个类在内存只存在一个对象的需求。
要保证对象唯一要满足以下几点:
1.为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2.为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
以上三点怎么用代码体现呢?
1.将构造函数私有化。
2.在类中创建一个本类对象。
3.提供一个方法可以获取到该对象。
其实对于所有的事物对象,当它需要保证在内存中唯一时,加上以上三步即可。
对于单例设计模式来说,它又分为两种情况,一种是饿汉式,一种是懒汉式。
饿汉式,先初始化对象。如下,Single类一进内存,就已经创建好了对象。
class Single{
privateSingle(){}//私有化构造函数。
privatestatic Single s = new Single();//创建Single对象。
publicstatic Single getInstance(){//提供方法使得外界可以获取该对象。
return s;
}
}
懒汉式,对象是方法被调用时才初始化,也叫做延时加载。Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
class Single{
private static Single s = null;//先不初始化。
private Single(){}
public static Single getInstance(){
if(s==null)//判断s是否为null,是即初始化。
s = new Single();
return s;
}
}
从以上两种方式,我们可以看出懒汉式会比饿汉式对于内存优化方面更有优势,因为它是需要时才加载,减少了对内存的浪费。但是懒汉式延时加载会存在安全问题,当有多线程访问时,如果前一个线程访问到if(s==null)这句代码,判断s为null,然后在执行初始化对象时线程暂时停止了,这时有另一个线程进行if(s==null)的判断,也是为true的,也会执行初始化语句。那么,等到前一个线程继续执行,其实内存中会存在不只一个Single对象。
所以,我们需要对懒汉式进行安全问题处理,可以加同步代码块或者同步函数。从代码可以看出操作共享数据的代码就是if(s==null)和s= new Single()这两句代码。可以将这两句代码放进同步代码块中,即
synchronized(Single.class){//这里要注意使用的锁是该方法所在类的字节码文件对象
if(s==null)
s = new Single(); }
但是这样做了之后,每个线程要继续判断锁,不管s是否已经被初始化了,这样会使得效率变低。为了解决效率低下的问题,可以在同步代码块之前加多一个判断语句,判断s是否已经被初始化,如果已经被初始化了,就可以直接跳过判断锁的语句了。即
if(s==null){
synchronized(Single.class){
if(s==null)
s = new Single();
}
}
return s;
利用双重判断的方式就可以解决效率问题啦。
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------
详细请查看:http://edu.csdn.net
相关文章推荐
- 黑马程序员——多线程(二)-单例设计模式
- 黑马程序员----------java基础加强之多线程、单例设计模式
- 黑马程序员_单例设计模式&多线程
- 黑马程序员--读写字节数组,随机读写流,集合IO的思维导图,多线程部分,单例设计模式,线程和进程的概念,Java中的线程的创建方式,线程的随机性,线程的状态图,多线程操作共享数据的安全性,死锁
- 黑马程序员_java语言_多线程和设计模式
- 【黑马程序员】多线程,设计模式——Java复习笔记
- 黑马程序员_多线程中的Lock锁,死锁以及单例设计模式分析
- 黑马程序员——多线程——多线程与单例设计模式
- 黑马程序员-------------多线程中的(线程、线程组、线程池、以及Java的设计模式)概念及方法的总结
- 黑马程序员-学习日志-单例设计模式
- 多线程学习之路-学习master-worker设计模式
- Java多线程编程实战指南(设计模式篇,黄文海)-之管道线模式
- 黑马程序员一单例设计模式的饿汉式与懒汉式以及加锁的情况
- 黑马程序员--设计模式——单例设计模式
- 黑马程序员---单列设计模式
- 黑马程序员7--单例设计模式
- Java多线程之并发协作生产者消费者设计模式
- 多线程、设计模式_总结
- java线程安全之多线程的设计模式(十四)
- C++模式设计-多线程下的单例模式