之前的日积月累专栏就是为了温故而知新,查漏补缺写的,现在的新专栏: 有趣的java数据结构,我会放一些有意思的数据结构和重要的知识点在里面
单例模式
自我理解
单例模式就是做一个 :不断去拿同一个事物,在做同一件事的小程序。这个同一个事物要求很苛刻。
举个例子:我要我今天刚买的那一只小猫,它两岁,我起名为橘喵,我只想带着它,而不是别的猫,哪怕这只猫和我的橘喵外貌,年龄都一模一样,但我能知道,这已经不是属于我的,那只我想要的猫了。
实例代码:
创建一个 猫 的类:
public class Cat {
private String name;
private int age;
public Cat() {
}
public Cat(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试类:
public class Test {
public static void main(String[] args) {
Cat cat1 = new Cat("橘喵", 3);
System.out.println(cat1);
Cat cat2 = new Cat("橘喵", 3);
System.out.println(cat2);
}
}
运行结果:
可以看出,即使两只猫的名字、年龄(name,age),甚至是外貌都一样,但灵魂(内存地址,即运行结果)是不一样的。
使用单例模式方法:
创建猫的类(单例模式:饿汉式)
public class Cat {
private static final Cat cat = new Cat();
private Cat() {
}
public static Cat getName() {
return cat;
}
}
创建猫的类(单例模式:懒汉式)
public class Cat {
private static Cat cat = null;
private Cat() {
}
public static synchronized Cat getName() {
if(cat == null) {
cat = new Cat();
}
return cat;
}
}
创建测试类:
public static void main(String[] args) {
Cat cat1 = Cat.getName();
System.out.println(cat1);
Cat cat2 = Cat.getName();
System.out.println(cat2);
}
}
运行结果:
现在,无论运行多少次,我拿到的是同一只猫(内存地址)了。
标准概念
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务; 一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化, 将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。
单例模式的要点有三个: 一是某个类只能有一个实例(对象); 二是它必须自行创建这个实例; 三是它必须自行向整个系统提供这个实例。
单例模式的目的: 保证该类只有一个对象。
怎么办?
第一步:把构造方法私有
第二步:在成员位置自己创建一个对象(即创建一个 成员变量)
第三步:通过一个公共的方法提供访问
单例模式的优点如下:
实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程。
Singleton模式主要作用是保证在Java应用程序中,一个类class只有一个实例存在。一般 Singleton模式通常有两种形式。
懒汉式和饿汉式的区别
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。
从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题、写法简单明了、能用则用。但是它是加载类时创建实例、所以如果是一个工厂模式、缓存了很多实例、那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。