单例设计模式用来创建唯一的对象,有些时候我们只需要一个对象,如:线程池,缓存,对话框,注册表,日志对象,等等。这就需要单例设计模式来完成。
不用多说,直接上代码。
public
class TestSingle {
private static TestSingle single = null;
private
TestSingle(){}
public static TestSingle
getInstance(){
if(single==null){
single = new
TestSingle();
}
return
single;
}
}
单例大家都知道,然而本文所讨论的单例重点为多线程下的单例模式
public class Test
{
public static void main(String[] args) {
Thread t1 = new Thread(new
Runnable() {
public void run() {
TestSingle t =
TestSingle.getInstance();
System.out.println(t);
}
});
Thread
t2 = new Thread(new Runnable() {
public void run() {
TestSingle t =
TestSingle.getInstance();
System.out.println(t);
}
});
Thread
t3 = new Thread(new Runnable() {
public void run() {
TestSingle t =
TestSingle.getInstance();
System.out.println(t);
}
});
t1.start();
t2.start();
t3.start();
TestSingle
t11 = TestSingle.getInstance();
TestSingle t22 =
TestSingle.getInstance();
TestSingle t33 =
TestSingle.getInstance();
System.out.println("123"+t11);
System.out.println("123"+t22);
System.out.println("123"+t33);
}
}
通过测试发现,上面的单例类所打印出的hashcode码是不同的。也就是说在多线程状态下,我们的单例不起作用了。
解决办法:
1.在TestSingle
getInstance()方法修改为public static synchronized TestSingle getInstance()
这样多线程就可以同步了。
2。采用急切实例化。即private static TestSingle single =
null;在声明时直接实例化该对象。
两种方法各有优缺点。第一种方法,在性能上或有下降。因为synchronized会影响性能。第二种方法,在jvm加载这个类的时候就创建改实例。
如果我们用不到改实例,为浪费。总之各有优缺点。
单例模式:
单件模式确保程序中一个类最多只有一个实例。
单件模式也提供访问这个实例的全局点。
在Java中实现单件模式需要私有的构造器,一个静态方法和一个静态变量。
确定在性能和资源上的限制,容纳后小心的选择适合的方案解决单件,以解决多线程的问题。
小心,你如果使用多个类加载器,可能导致单例的失效而产生多个实例。