思路:
1、如果其他程序能够随意用new创建该类对象,那么就无法控制个数。因此,不让其他程序用new创建该类的对象。
2、既然不让其他程序new该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了。
3、该类将创建的对象对外(整个系统)提供,让其他程序获取并使用。
步骤:
1、 将该类中的构造函数私有化。
2、在本类中创建一个本类对象。
3、定义一个方法,返回值类型是本类类型。让其他程序通过该方法就可以获取到该类对象。
第一种方法:
//饿汉式
public class Single {
/**
* 构造成一份,并且成用final声明成常量
*/
private final static Single s = new Single();
/**
* 私有化构造函数,防止外部new本类对象
*
*/
private Single(){
}
/**
* 外部通过调用这个函数来拿到对象
* @return Single对象s
*/
public static Single getInstance(){
return s; //这里是实例对象,因此需要设置static
}
}
测试代码如下:
/**
* 此时若地址一样,则拿的是同一对象
*/
@Test
public void t1() {
Single s1 = Single.getInstance();
System.out.println(s1);
Single s2 = Single.getInstance();
System.out.println(s2);
}
测试结果如下:
SingelModel.pattern.singleton.Single@50c931fc
SingelModel.pattern.singleton.Single@50c931fc
第二种方法:
public class Single2 {
//懒汉式
private static Single2 s= null;
private Single2(){
}
public static Single2 getInstance(){ 这里有一Bug,当用于线程时会有两个s==null为true,因此会出现异类地址
if(s==null){
s = new Single2();
}
return s;
}
}
测试代码如下:
@Test
public void t2() {
Thread ts[] = new Thread[100];
for (int i = 0; i < ts.length; i++) {
ts[i] = new UseSingle2();
}
/**
* 一起启动线程
*/
for (int i = 0; i < ts.length; i++) {
ts[i].start();
}
}
class UseSingle2 extends Thread {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Single2 s = Single2.getInstance();
System.out.println(s);
}
测试结果如下:
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@488e32e7 ******
SingelModel.pattern.singleton.Single2@2d342ba4
SingelModel.pattern.singleton.Single2@2d342ba4
第三种方法:是借用了单例的思想,
/**
* 这里是单例的第三种模式,可以再Single3中随便new ,
* 但是却只能拿到A类中的同一个对象
* @author Administrator
*
*/
public class Single3 {
private final static A a = new A(); //单例
public A getA(){
return a;
}
}
public class A {
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
@Test
public void t3() {
A a1 = new Single3().getA();
A a2 = new Single3().getA();
A a3 = new Single3().getA();
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
}
结果如下:SingelModel.pattern.singleton.A@3603820e
SingelModel.pattern.singleton.A@3603820e
SingelModel.pattern.singleton.A@3603820e