拥有独立且唯一的对象
这次讲述的是单件模式,就是整个内容里只有一个实例化“唯一”对象。这么说可能有点拗口,这么说吧,比方说,线程池,缓存,注册表,日志文件,甚至做JDBC中连接,关闭,增删改查数据库的Connection类(个人命名也许并不一样)、工具类等等。这些东西往往是要实例一次,就能在整个项目中使用了。
单件模式并不难理解定义如下
单件模式:确保一个类中只有一个实例,并提供一个全局访问点。
是的就这么一句话的定义。一般单件模式分为“懒汉式”和“饿汉式”做法
直接上代码。
“懒汉式”做法
package singleton01;
public class Singleton01 {
// 利用一个静态变量记录本类当中唯一的实例(mySingleton01)
private static Singleton01 mySingleton01 = null;
public Singleton01() {
}
// synchronized关键字:线程同步锁,在多线程中去互斥地访问临界资源
// 迫使每个线程在进入方法之前,要先等别的线程执行完离开方法后才能执行,达到多个线程排队,不会造成有多个线程同时进入这个方法
// 即是同步。但同步会使程序效率降低
public static synchronized Singleton01 getInstance() {
if (mySingleton01 == null) {
mySingleton01 = new Singleton01();
System.out.println("Singleton01被实例化了");
}
System.out.println("返回Singleton01实例");
return mySingleton01;
}
/**
* 上面方法就是常说了“懒汉式”做法,大体意思就是当谁需要类方法时采取实例化
*/
}
package singleton01;
public class TestMain {
public static void main(String[] args) {
// 打印出前两行结果
Singleton01 singleton01 = Singleton01.getInstance();
// 此时我们看到第二次调用类方法时候,没有去实例对象
// 这里涉及并发方面问题,暂时没学习并发,具体怎么个原理我也不知道...
Singleton01 singleton02 = Singleton01.getInstance();
}
}
效果图1
效果图2
之前的做法中我们用到了synchronized,就是为了防止线程启动的随机性找出变量混乱,我这个小例子可能看不出来什么。但实际上同步线程(synchronized)会使得程序效率大幅降低。利用双重检查加锁可以有效解决此问题,
使用双重检查加锁
package singleton01;
public class singleton02 {
// 利用双重检查加锁,先检查实例是否已经创建,如果没创建,就进行同步。
// volatile:instance变量被初始化singleton02实例时,多个线程会正确处理instance变量
// 线程是具有随机性的,与程序执行顺序无关。
private volatile static singleton02 instance=null;
public singleton02() {
}
public static singleton02 getInstance() {
if (instance == null) {
// 检查实例,不存在的话进入同步区域,只有第一次才执行这里
synchronized (singleton02.class) {
System.out.println("进入同步区域");
if (instance == null) {
System.out.println("instance被实例化了");
instance = new singleton02();
}
}
}
System.out.println("返回instance实例");
return instance;
}
}
package singleton01;
public class TestMain02 {
public static void main(String[] args) {
//第一次进入方法会进入同步区实例化
singleton02 singleton02 = null;
singleton02 = singleton02.getInstance();
//当第二次进入时,已有实例,不会同步了,直接返回实例.
singleton02 singleton03 = null;
singleton03 = singleton02.getInstance();
}
}
效果图
"饿汉式"做法
package singleton02;
public class Singleton {
/**
* “饿汉式”:加载这个类时立刻创建本类中唯一的单件实例,
*/
private static Singleton uniqueInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
System.out.println("返回实例实例");
return uniqueInstance;
}
}
package singleton02;
public class TestMain {
public static void main(String[] args) {
//直接返回实例
Singleton singleton = Singleton.getInstance();
}
}
效果图
注:双重检查加锁不适用与1.4之前的java版本。
要点:
1、单件模式确保程序中一个类最多只有一个实例。
2、单件模式提供这个实例的全局访问点。
3、实现单件模式,需要私有构造器,一个静态方法,一个静态变量。
4、设计到多线程问题,同步会降低程序效率。
感谢你看到这里,至此单件模式内容结束,本人文笔随便,若有不足或错误之处望给予指点,90度弯腰~~~很快我会发布下一个设计模式内容,生命不息,编程不止!
参考书籍:《Head First 设计模式》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。