单例模式定义:
该种模式设计也给单一的类, 简单来说就是我创建我自己, 使得内存中只有一个对象.
为什么这样做呢, 因为在 Java 中, 创建对象是需要消耗资源的, 如果一个类放在全局中, 它的实例可能会被频繁地创建和销毁, 那么我把类构造器器私有化, 那么一个类只有一个实例, 我一是控制了实例地数目, 二是节约了资源, 三提供了可以访问的全局访问点. 举个例子, 一些设备管理器常常被设计为单例模式, 系统在操作文件的时候, 就不可避免出现多个线程或者进程同时操作一个文件, 所以该要通过唯一一个实例来进行处理.
懒汉模式: 在类加载的时候不被初始化, 而是在需要的时候才会被初始化, 因此不加锁的情况下不是多线程安全的.
饿汉模式: 在类加载的时候就被初始化了. 由于基于 classloader 机制避免了多线程同步的问题, 但是在类加载的时候就初始化, 也浪费了内存.
那么, 由单例模式就引出了三个问题:
1. 设计一个饿汉模式, 该类构造方法私有化.
- class Singleton{
- // 为什么这里要私有化, 因为如果在外部访问的化, 虽然我可以创建俩个不同名字的静态实例都是指向同一个地址, 但是我也可以把其中一个置为空, 但是就不符合单例模式思想了
- private staitc Singleton instance = new Singleton();
- // 为什么构造函数私有化, 这样该类就不能被被外部实例化了.
- private Singleton(){}
- // 提供一个外部的接口用来调用内部的静态实例
- public static Singleton getInstance(){
- return instance;
- }
- }
2.Java 中有哪些模式是单例模式:
Runtime 类, Pattern 类
3. 设计一个线程同步的懒汉模式:
- class Singleton{
- //volatitle 保证了内存可见
- private static volatile Singleton instance = null;
- private Singleton() {
- }
- public static Singleton getInstance() {
- if(instance == null) {
- // 为什么不在 getInstance 加锁, 因为只有 instance 为空的时候才会发生抢, 这就导致了函数加锁后接下来不为空的情况每次只能有一个线程访问, 效率太低.
- synchronized(Singleton.class) {
- // 线程们抢到了 getInsrance, 但是由于 volatitle, 只有一个线程能创建 isntance, 所以在这里还要判断一次, 而且创建完了以后调用都走不到这里了.
- if(instance == null) {
- instance = new Singleton();
- }
- }
- }
- return instance;
- }
- }
参考文章:
单例模式 (懒汉式和饿汉式区别)
单例模式
从 jvm 的角度来看单例模式 https://www.cnblogs.com/chenliyang/p/6548374.html
来源: http://www.bubuko.com/infodetail-3346753.html