黑马程序员_java基础学习笔记之单例设计模式

------- android培训java培训、期待与您交流! ----------


单例设计模式

设计模式:解决某一类问题行之有效的方法。Java中有23中设计模式。

单例设计模式:解决一个类在内存中只存在一个对象。

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

单例设计模式三步骤:
1.将构造函数私有化。
2.在类中创建一个本类对象。
3.提供一个方法可以获取到该对象。
(对于事物怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上三步加上即可。)


单例模式根据实例化对象时机的不同分为两种:一种是饿汉式,一种是懒汉式。

单例设计模式的第一种方法:是先初始化对象,类进入内存时就已近存在对象,昵称为“饿汉式”。

单例设计模式的第二种方法:类进入内存时还没有存在对象,只有当调用get类方法时才才初始化对象,也叫做对象的延时加载,昵称为“懒汉式”。


class student
{
private int age;

//第一种方式:饿汉式

/*
//创建本类对象
private static student s=newstudent();
//私有化构造函数
private student(){}
//返回本类对象,该对象只存在一个。
public static student getstudent()
{
return s;
}

*/

//第二种方式:懒汉式

//student类进内存,对象还没有存在,只能调用了getinstance方法时,才建立对象。
/*

//创建本类对象
private static student snull;
//私有化构造函数
private student(){}
//返回本类对象,该对象只存在一个。
public static student getstudent()
{
if(s == null)
p = new student();
return s;
}

*/
public void setAge(int age)
{
this.age=age;
}
public int getAge()
{
return age;
}
}
class demo
{
public static void main(string[] args)
{
student s1=student.getstudent();
student s2=student.genstudent();
s1.setAge(20);
s2.setAge(23);
//输出结果都是23,因为p1和p2都指向同一个对象
System.out.println(s1.getAge());
System.out.println(s2.getAge());
}
}
记录原则:定义单例,建议使用饿汉式。

饿汉式和懒汉式的区别:饿汉式单列在单列类被加载时候,就实例化一个对象给自己的引用。而懒汉式在调用取得实例方法的时候才会实例化对象。

在开发过程中,一般使用第一种方法,即“饿汉式”。因为第二种方法存在安全问题(当多个人同时调用该方法时,会存在安全问题)。

懒汉式单例在实际开发中不常用,但是在面试中常见。


多线程懒汉式单例设计:

分析:多线程懒汉式单例设计中,会出现问题的代码位于getInstance方法中。因为当对象称都判断

因为当多个线程都判断s==null,执行s==null后,由于为获取cup执行权,停止在new Single之前,当获取cup执行权后,所有的线程都会执行new Single(),造成对象不唯一。

如下:

classSingle{

private static Singles = null;
public Single(){}
public static Single getInstance() {
if(s ==null)
s = new Single();
return s;
}
}
在getInstance方法添加同步关键字,变成同步函数。但是如果改为同步函数后,会造成效率低。

如:if(s == null)
s = new Single();

但若改为同步代码块,效率也比较低,因为每次都要判断锁。

如:public static Single getInstance() {

synchronized(Single.class) {
if(s == null)
s = new Single();
}

return s;
}

所以可以选择双重判断,提高效率。当第1、2线程进入s=null,第1个线程获得锁,第2个线程被锁在外面,所以第1个线程创建s=new Single()对象。

当第2个线程获取cup执行权后,s不为空,所以不执行创建对象语句。当猴续的进城执行getInstance方法后,s不为空,所以不执行下面的语句,直接return s。

如下:

public static Single getInstance() {

if(s == null) {

synchronized (Single.class){
if(s == null)
s = new Single();

}
return s;
}

总结:多线程懒汉式单例设计模式的特点时,双重判断加代码同步synchronized。多线程中懒汉式单例设计模式的锁是该类的字节码文件对象。





你可能感兴趣的:(Java基础,黑马程序员,java,设计模式,多线程,安全)