一、单例模式
单例模式就是确保某个类只有一个实例,并且该类只提供一个获取其对象实例的方式。分为饿汉式和懒汉式。
饿汉式实现步骤:
- 构造器私有化
- 类的内部创建对象
- 向外部暴露一个静态公共方法
public class Home {
public static void main(String[] args) {
Girl girl = Girl.getInstance();
}
}
class Girl {
private String name;
//在类的内部创建这个类的实例
private static Girl girl = new Girl("name");
//构造器私有化
private Girl(String name) {
this.name = name;
}
//创建一个返回对象的公共方法
public static Girl getInstance() {
return girl;
}
}
懒汉式实现步骤:
- 仍然構造器私有化
- 定義一個 static 靜態屬性對象
- 提供一個 public 的 static 方法,可以返回一個 Girl對象
- 懶漢式,只有當用戶使用 getGirl 時,才返回 Girl對象, 後面再次調用時,會返回上次創建的 Girl對象
public class Home {
public static void main(String[] args) {
Girl girl = Girl.getInstance();
}
}
class Girl {
private String name;
// 定义静态属性对象,默认是null
private static Girl girl;
private Girl(String name) {
this.name = name;
}
public static Girl getInstance() {
// 只有第一次调用的时候去创建Girl对象实例
if (girl == null) {
girl = new Girl("name");
}
return girl;
}
}
但是懒汉式存在线程安全问题,想要解决只要在方法加上synchronized即可。
public static synchronized Girl getInstance() {
加上synchronized的话又会导致效率低下,使用双重检查改进:
public static Girl getInstance() {
// 只有第一次调用的时候去创建Girl对象实例
if (girl == null) {
synchronized (Girl.class) {
if (girl == null) {
girl = new Girl("name");
}
}
}
return girl;
}
Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (girl == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (girl == null),直接return实例化对象。
优点:线程安全;延迟加载;效率较高。
饿汉式和懒汉式区别:
- 两者最重要的区别是创建对象实例的时机不同,饿汉式是在类加载的时候就创建了对象,而懒汉式是在使用时才会去创建。
- 饿汉式不存在线程安全问题,而懒汉式存在线程安全问题
- 饿汉式存在资源浪费问题,饿汉式没有去使用这个对象实例的话,那这个对象就浪费了,而懒汉式是使用的时候才创建所以不存在这个问题。
- java.lang.Runtime 就是经典的单例模式
二、抽象类-模板设计模式
public class AA extends Template {
// 计算任务
// 1+....+ 800000
@Override
public void job() { // 实现 Template 的抽象方法 job
long num = 0;
for (long i = 1; i <= 800000; i++) {
num += i;
}
}
public void job2() { // //得到开始的时间
long start = System.currentTimeMillis();
long num = 0;
for (long i = 1; i <= 200000; i++) {
num += i;
} // 得的结束的时间
long end = System.currentTimeMillis();
System.out.println("AA 执行时间 " + (end - start));
}
}
public class BB extends Template {
@Override
public void job() { // 这里也去,重写了 Template 的 job 方法
long num = 0;
for (long i = 1; i <= 80000; i++) {
num *= i;
}
}
}
public class TestTemplate {
public static void main(String[] args) {
AA aa = new AA();
aa.calculateTime(); // 这里还是需要有良好的 OOP 基础,对多态
BB bb = new BB();
bb.calculateTime();
}
}
网友评论