当前业界主流的网站建设外贸网站平台都有哪些
前言
单例模式是日常开发中最常见的一种设计模式,常用来做为池对象,或者计数器之类的需要保证全局唯一的场景。
单例模式的目的是保证在整个程序中只存在一个对象实例,使用单例一个前提条件就是构造器私有化,不允许通过new 对象的方式。单例模式的实现主要方式有如下几种:
1、饿汉式实现
2、使用枚举类实现
3、懒汉式使用双重检查锁实现。
4、使用静态内部类实现
“饿汉式”
饿汉式:顾名思义就是很"饥饿",初始化就创建设好了实例。
public class Demo1 {private static Demo1 demo1 = new Demo1();private void Demo1() {}public static Demo1 getInstance() {return demo1;}
}
“懒汉式” -双重检查锁
为什么要使用双重检查锁?因为如果在并发的状态下,如果A线程先进来,判断demo2为null,然后创建实例对象,在判断了为null的这个时间点,B线程也进来了判断demo2为null,也去创建实例,这样就不能保证单例。
public class Demo2 {private volatile static Demo2 demo2 = null;private void Demo2() {}public static Demo2 getInstance() {if (demo2 == null) {synchronized(Demo2.class) {if (demo2 == null) {demo2 = new Demo2();}}}return demo2;}}
“懒汉式” -使用静态内部类的方式实现
使用静态内部类的方式实现的单例式利用了java的特性,就是static属于类,在初始化的时候就已经执行了,且static修饰的对象或者静态代码块只执行一次。
public class Demo3 {private static Demo3 demo3;private void Demo3() {}private static class HolderClass {private static Demo3 demo3 = new Demo3();}public static Demo3 getInstance() {return HolderClass.demo3;}
}
枚举方式
枚举方式利用了枚举的特性,enum修饰的类被称之为枚举类,java不允许通过反射来创建enum类,同时enum修饰的类默认继承了Enum类,其构造函数为private修饰的,因此枚举类具有天然的单例特性,很适合用做单例模式。
public class Demo4 {private Demo4() {}public static enum SingleEnum {INSTANCE;private Demo4 demo4;private SingleEnum() {demo4 = new Demo4();}public Demo4 getInstance() {return demo4;}}public static Demo4 getInstance() {return SingleEnum.INSTANCE.getInstance();}// 测试public static void main(String[] args) {Demo4 instance = getInstance();}
}
下面来看一个单例模式的典型应用场景:
JefLogTail采集工具中的server端,在处理日志多线程入库时,为了防止反复的创建线程池导致服务器压力大,因此采用单例模式来定义线程池的获取。如下:
public class LogHandle extends ServerMessageHandler {private LogSave logSave;@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, Message message) throws Exception {try {
/* String content = (String) message.getContent();String ip = message.getAttachment("ip");String fileName = message.getAttachment("fileName");System.out.println("ip地址:" + ip);System.out.println("文件名称:" + fileName);*/ThreadPoolCfg.getThreadPool().execute(new Runnable() {@Overridepublic void run() {logSave.save(message);}});// 多线程处理} catch (Exception e) {e.printStackTrace();}}public void setLogSavePlan(LogSave logSave) {this.logSave = logSave;}
}