![](https://csdnimg.cn/release/download_crawler_static/86307582/bg1.jpg)
前面讲完了很多关于多线程的内容,包括各种关键字和一些包的用法,还有类的加载等内容,那么下面将讲解一下一些常见的多线程的相关的设计模式。那
么为什么需要讲设计模式呢?因为很多时候一些成员变量需要保证只实例化一次,或者线程的状态需要得到监控,甚至考虑一些不使用锁的机制来保证安全
性等等,那么这些都是需要通过优秀的设计模式来实现的。那么首先第一个要讲的就是几种常见的单例设计模式,该模式在多线程下保证了实例的唯一性。
而实现该模式的方法有很多,可以从线程安全、高性能和懒加载来评估。
1. 饿汉式饿汉式(类加载过程中直接初始化类加载过程中直接初始化)
public class Singleton {
//实例变量
private byte[] data = new byte[1024];
//在定义实例对象的时候直接初始化
private static Singleton instance = new Singleton();
//私有构造函数,不允许外部new
private Singleton() {
}
public static Singleton getInstance() {
System.out.println("******"+Singleton.class.getName());
return instance;
}
}
这里注意构造方法那里加了private的话,那么就无法使用new来构造了,但是可以直接调用
public class signalModeTest1 {
public static void main(String[] args) {
//测试饿汉式
Singleton.getInstance();
}
}
然后这里的运行结果输出就是System的结果,这种方式就是因为instance作为类变量在类初始化的过程中会被收集进()方法中,该方法能够保证同步,因此
就不会被实例化多次。但是这样就意味着如果这个变量长期不用的话,那么就会存放在内存当中,导致占用资源了,因此虽然性能不错,但是适用范围不
大。
2. 懒汉式懒汉式(使用时实例化使用时实例化)
2.1 无同步方法无同步方法
public class Signleton_lazy {
//实例变量
private byte[] data = new byte[1024];
//在定义实例对象的时候不初始化
private static Signleton_lazy instance = null;
public Signleton_lazy() { }
public static Signleton_lazy getInstance() {
System.out.println("******"+Signleton_lazy.class.getName());
if(null == instance) {
instance = new Signleton_lazy();
}
return instance;
}
}
这个方法的特点就是修改了初始化,只有在调用getInstance的时候才实例化,这样就保证了使用时才实例化,但是如果在多线程的环境下还是有问题的,因
为如果在new的时候,刚好也有另外一个线程进行判断,但是这时候还没实例化完成,所以会导致多次实例化,因此下面需要改进一下。
2.2同步方法同步方法
public static synchronized Signleton_lazy getInstance() {
System.out.println("******"+Signleton_lazy.class.getName());
if(null == instance) {
instance = new Signleton_lazy();
}
return instance;
}