前言:
在我们开发项目的时候,需要考虑项目的资源占用情况,减少项目的资源占用,提高执行效率。那么单例模式则是必不可少的一种开发模式。
何为单例模式:
单例模式顾名思义就只在内存中存在一个对象,用这个对象来满足方法的调用。这样减少了new的步骤,也就减少了资源的占用。
1.饿汉模式
一般在多线程的情况下,这种单例模式用的比较多,用哪种单例模式还的看自己项目情况。这种模式一旦项目编译启动了就开始创建对象。这种模式适用于多线程。
package 单例模式;
/*
饿汉模式 (项目编译好就加载)
只有一个对象,
只能在使用该类的时候创建,
这样才能保证在内存中只存在一个对象。
*/
public class HungrySingleTon {
//在创建一个类的时候直接创建
private final static HungrySingleTon instance=new HungrySingleTon();
HungrySingleTon(){
}
//然后返回一个内存地址
public static HungrySingleTon getInstance(){
return HungrySingleTon.instance;
//JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样能保证instance只被创建一次
//防止多线程并发导致创建多个实例
}
}
饿汉模式与普通模式所分配的内存
2.懒汉模式
这种模式适用于单线程的项目,用于使用时加载类的情况。但这种模式不安全。当用多线程的时候,可能会由于并发导致创建多个实例对象出来。
//在创建的时候来判断有没有创建实例,没创建新创建一个
//这种方式不安全,再多线程中 会实例出多个对象出来
public static LazySingleTon getInstance(){
if (lazySingleTon==null){
lazySingleTon=new LazySingleTon();
}
return lazySingleTon;
}
优化一下 用synchronized同步加锁即可解决
但这样虽然避免了多线程中由于执行速度过快导致的多个实例被创建,但是每次调用这种getinstance的时候都会给实例对象同步加锁,这样会降低程序执行的效率。
//同步加锁后就能保证线程安全,但效率就变低了(每次调用getInstance 都要同步上锁)
public static synchronized LazySingleTon getInstance(){
if (lazySingleTon==null){
lazySingleTon=new LazySingleTon();
}
return lazySingleTon;
}
最后,用代码块来提高效率并提高安全性
在每次调用方法getInstance的时候,先判断对象是否被创建。再决定加不加锁创建对象。
//效率高且比较安全的一种懒汉单例模式
public static LazySingleTon getInstance(){
if (lazySingleTon==null){
//使用代码块提高效率
lazySingleTon = new LazySingleTon();
synchronized (lazySingleTon){ }
}
return lazySingleTon;
}
测试类
package 单例模式;
public class test {
public static void main(String[] args) {
HungrySingleTon hungrySingleTon =new HungrySingleTon();
HungrySingleTon hungrySingleTon1 =new HungrySingleTon();
commonMode commonMode=new commonMode();
commonMode commonMode1=new commonMode();
LazySingleTon lazySingleTon=new LazySingleTon();
LazySingleTon lazySingleTon1=new LazySingleTon();
HungrySingleTon test1= hungrySingleTon1.getInstance();
LazySingleTon lazy1=lazySingleTon.getInstance();
System.out.println(test1.toString());
System.out.println(commonMode.toString());
System.out.println(lazy1.toString());
new Thread(new Runnable() {
@Override
public void run() {
HungrySingleTon test2= hungrySingleTon1.getInstance();
LazySingleTon lazy2=lazySingleTon1.getInstance();
System.out.println(test2.toString());
System.out.println(commonMode1.toString());
System.out.println(lazy2.toString());
}
}).start();
}
}
运行结果
以上内容由自己整理思路发布,如有错误欢迎指正 😊