java23种设计模式
里氏代换原则,适配器模式
单例模式:一个类只能有一个实例
①对于单例类来说,可以有其他的属性,也可以有静态和非静态的其他方法。
②要求按照既定的步骤来执行,就能实现一个单例:
1)私有构造方法
2)提供一个私有的属性,该属性是该类一个静态私有对象。
3)提供一个静态的getter方法,供外界访问。
4)理论上,懒汉式要优于饿汉式,提高了空间的利用率,但是在实际开发中,使用饿汉式居多。懒汉式有线程安全问题,对于懒汉式来说需要解决线程的安全问题,比对空间利用率来说,线程安全问题更难解决。
饿汉式:类一加载就创建实例
弊端:用类的其他方法时,也会创建这个类的实例
class SingleB{//饿汉式。一存在就创建
//私有构造方法
private SingleB() {}
//私有静态实例属性
private static SingleB instance = new SingleB();
//公有静态get方法
public static SingleB getInstance() {
return instance;
}
}
懒汉式:什么时候用什么时候创建
解决了饿汉式问题,但是存在线程安全问题。
因为在if判断时会产生线程安全问题。
解决线程问题:加锁,但是加锁就是单线程了,运行速度会慢,我们只需要在他第一次创建的时候进行控制。
class SingleAPlus{
private SingleAPlus(){
}
private static SingleAPlus instance = null;
public static SingleAPlus getInstance() {
// 第一层检查,多线程中可能有很多线程都进去if
if (instance == null) {
synchronized (SingleAPlus.class) {
//判断是否存在实例
//如果没有第二层检查,那么第一个线程创建完对象释放锁后,后面进入对象也会创建对象,会产生多个对象。因为进入第一层的线程可能有很多
if (instance == null) {
try {
Thread.sleep(100);//为了扩大这个问题,所以加睡眠。测试时使用,真实使用要删除这句。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
instance = new SingleAPlus();
}
}
}
return instance;
}
}
完整代码
/**
* 作者: 帅的一批
* 学习:设计模式 23种
* 内容:单例模式
* 前提:一个类只能有一个实例
* 饿汉式:上来就创建对象
* 懒汉式:用的时候才创建对象
* 懒汉式不用每次都创建对象,但是存在线程安全问题
* 怎么产生线程安全?同样道理。在if条件里,多线程运行可能会多个进入if然后进行操作
* 解决:加锁,但是加锁就是单线程了,运行速度会慢,我们只需要在他第一次创建的时候进行控制,所以可以再加一层if判断
*/
public class SingleTonStudy1 {
public static void main(String[] args) {
//懒汉式
SingleA sA = SingleA.getInstance();
SingleA sA2 = SingleA.getInstance();
System.out.println(sA==sA2);
//饿汉式
SingleB sB = SingleB.getInstance();
SingleB sBB = SingleB.getInstance();
System.out.println(sB==sBB);
//懒汉式线程安全问题,创建两个线程同时抢这创建这个类的实例
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
SingleAPlus s1 = SingleAPlus.getInstance();
System.out.println(s1);
}
}.start();
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
SingleAPlus s2 = SingleAPlus.getInstance();
System.out.println(s2);
}
}.start();
}
}
class SingleA{ //什么时候用,什么时候创建
private SingleA(){
//构造方法私有化
}
//静态实例成员
private static SingleA instance = null;
//公有get方法,静态
public static SingleA getInstance() {
//判断是否存在实例
if (instance == null) {
instance = new SingleA();
}
return instance;
}
}
class SingleB{//饿汉式。一存在就创建
//私有构造方法
private SingleB() {}
//私有静态实例属性
private static SingleB instance = new SingleB();
//公有静态get方法
public static SingleB getInstance() {
return instance;
}
}
class SingleAPlus{
private SingleAPlus(){
}
private static SingleAPlus instance = null;
public static SingleAPlus getInstance() {
if (instance == null) {
synchronized (SingleAPlus.class) {
//判断是否存在实例
if (instance == null) {
try {
Thread.sleep(100);//为了扩大这个问题,所以加睡眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
instance = new SingleAPlus();
}
}
}
return instance;
}
}