先介绍下(上网搜的解释,如果不明可以百度一下)
单件模式用途:
单件模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。
单件模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。它的用途十分广泛,打个比方,我们开发了一个简单的留言板,用户的每一次留言都要将留言信息写入到数据库中,最直观的方法是没次写入都建立一个数据库的链接。这是个简单的方法,在不考虑并发的时候这也是个不错的选择。但实际上,一个网站是并发的,并且有可能是存在大量并发操作的。如果我们对每次写入都创建一个数据库连接,那么很容易的系统会出现瓶颈,系统的精力将会很多的放在维护链接上而非直接查询操作上。这显然是不可取的。
如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和cpu利用率。这就是单件模式的用途。当然单件模式不仅仅只用于这样的情况。在《设计模式:可复用面向对象软件的基础》一书中对单件模式的适用性有如下描述:
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
饿汉式与懒汉式区别:
饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。
懒汉式:当程序第一次访问单件模式实例时才进行创建
入主题:
1、饿汉式单例
Demo1.java
package com.gx.singleton;
public class Demo1 {
public static void main(String[] args) {
SingletonOne s1=SingletonOne.getInstance();
s1.setInta(1);//写入
s1.method();//打印出:方法
//SingletonOne.getInstance() 调用公共类SingletonOne下的静态方法getInstance()
SingletonOne s2=SingletonOne.getInstance();
SingletonOne s3=SingletonOne.getInstance();
SingletonOne s7=SingletonOne.getInstance();
s7.setInta(7);
//s7.equals(s4);
// == 双等判断是以储存路径进行判断 (故值也一样了)
// equals 判断值是否相等
System.out.println("s1==s7:"+(s1==s7));//判断s1==s7 存储路径是否相等,相等即s1与s7为同一对象
//inta 直接点点不出(private私有的) 通过对于的get set 进行操作 inta私有字段
System.err.println("s1.getInta():"+ s1.getInta());
System.err.println("s1.inta:"+ s1.intaa);
s1.print();
}
}
SingletonOne.java
package com.gx.singleton;
//单例类
/**
* 饿汉式单例
* (类似只能打开一次,有特殊情况:反射机制(能打破一切的修饰符、封装的限制))
*
* @author en
*
*/
public class SingletonOne {
{ System.err.println("已经创建");}
//实例化这个类 (实例自身)
private static SingletonOne instance=new SingletonOne();
//1、隐藏构造器
private SingletonOne(){
System.err.println("隐藏构造器 饿汉式单例");
}
//创建静态工厂方法 ,让外部可以获取实例 get Instance:获取实例
public static SingletonOne getInstance(){
return instance;
}
//===================
private int inta;//private 私有的
public int intaa;
public int getInta() {
return inta;
}
public void setInta(int inta) {
this.inta = inta;
}
public void print(){
System.out.println("SingletonOne 打印 inta="+inta);
}
public void method(){
System.err.println("方法");
}
}
2、懒汉式单例
Demo2.java
package com.gx.singleton;
public class Demo2 {
public static void main(String[] args) {
SingletonTwo s1=SingletonTwo.getInstance();
SingletonTwo s2=SingletonTwo.getInstance();
System.out.println(s1==s2);
}
}
SingletonTwo.java
package com.gx.singleton;
/**
* 懒汉式单例
*
* @author en
*
*/
//用到synchronized
//synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
//1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
//2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
//3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
//4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
//注意:synchronized(同步锁)在同一时刻只能有一个线程得到执行,另一个线程受阻塞,
//必须等待当前线程执行完这个代码块以后才能执行该代码块。而创建s1和s2两个synchronized锁定同一对象
//,s1、s2互相不影响对方
public class SingletonTwo {
private static SingletonTwo instance = null;
// 1、隐藏构造器
private SingletonTwo() {
}
// 创建静态工厂方法 ,让外部可以获取实例(有小问题)
// public static SingletonTwo getInstance() {
// if (instance==null) {
// instance=new SingletonTwo();
// }
// return instance;
// }
// 静态工厂方法
// 双重检查锁定 保证线程安全
// synchronized 在多线程访问的时候,同一时刻只能有一个线程能够用synchronized 修饰的方法 或者 代码块。
public static SingletonTwo getInstance() {
if (instance == null) {
synchronized (SingletonTwo.class) {
if (instance == null) {
instance = new SingletonTwo();
}
}
}
return instance;
}
}
------------------------------------------------------------------------补充---------------------------------------------------------
工厂方法模式代码
interface IProduct {
public void productMethod();
}
class Product implements IProduct {
public void productMethod() {
System.out.println("产品");
}
}
interface IFactory {
public IProduct createProduct();
}
class Factory implements IFactory {
public IProduct createProduct() {
return new Product();
}
}
public class Client {
public static void main(String[] args) {
IFactory factory = new Factory();
IProduct prodect = factory.createProduct();
prodect.productMethod();
}
}
抽象工厂模式代码
interface IProduct1 {
public void show();
}
interface IProduct2 {
public void show();
}
class Product1 implements IProduct1 {
public void show() {
System.out.println("这是1型产品");
}
}
class Product2 implements IProduct2 {
public void show() {
System.out.println("这是2型产品");
}
}
interface IFactory {
public IProduct1 createProduct1();
public IProduct2 createProduct2();
}
class Factory implements IFactory{
public IProduct1 createProduct1() {
return new Product1();
}
public IProduct2 createProduct2() {
return new Product2();
}
}
public class Client {
public static void main(String[] args){
IFactory factory = new Factory();
factory.createProduct1().show();
factory.createProduct2().show();
}
}