设计模式
一、单例模式
单例模式的特点:单例类只能有一个实例;单例类必须自己创建自己唯一的实例;单例类必须给所有其他对象提供这唯一实例
1、懒汉式
/**
* 懒汉式单例模式,在第一次调用的时候实例化自己
*/
@Getter
@Setter
public class Singleton {
private String name;
private Singleton(){}
private static Singleton single;
/**
* 静态工厂方法
* 存在线程安全问题,线程不安全的
* @return single
*/
public static Singleton getInstance(){
if(single==null){
single = new Singleton();
}
return single;
}
/**
* 同步方法 线程安全的 效率低
* @return single
*/
public static synchronized Singleton getInstanceSynchronized(){
if(single==null){
single = new Singleton();
}
return single;
}
/**
* 双重校验锁定
* @return single
*/
public static Singleton getInstanceTwoCheck(){
if (single==null){
synchronized (Singleton.class){
if (single==null){
single = new Singleton();
}
}
}
return single;
}
//静态类部类(推荐使用)
public static class LazyHolder{
private static final Singleton SINGLE = new Singleton();
}
public static final Singleton getInstanceLazyHolder(){
return LazyHolder.SINGLE;
}
}
2、饿汉式
/**
* 饿汉式单例模式
*/
public class HungryHanStyle {
//饿汉式单例类.在类初始化时,已经自行实例化,以后不再改变,所以天生是线程安全的
private static final HungryHanStyle HAN_STYLE = new HungryHanStyle();
private HungryHanStyle(){}
public static HungryHanStyle getInstance(){
return HAN_STYLE;
}
}
3、登记式单例
/**
* 登记式单例
*/
public class RegisteredSingleExample {
//集合存放实例对象
private static Map<String,RegisteredSingleExample> map = new HashMap<>();
//保护的默认构造方法
protected RegisteredSingleExample(){};
//创建返回唯一实例的静态工厂
public static RegisteredSingleExample getInstance(String name) throws ClassNotFoundException, IllegalAccessException, InstantiationException
if (name==null){
name = RegisteredSingleExample.class.getName();
}
//判断是否存在改实例对象,若不存在则创建
if (map.get(name)==null){
map.put(name, (RegisteredSingleExample) Class.forName(name).newInstance());
}
return map.get(name);
}
public Map<String,RegisteredSingleExample> getMap(){
return map;
}
}
//继承RegisteredSingleExample;单例对象存入map集合,下次可直接调用,不需要从新实例化
public class Registered extends RegisteredSingleExample {
public static Registered getInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return (Registered) Registered.getInstance("com.zgq.entity.dto.Registered");//这里调用的是父类的方法,这里发生了向下转换
}
}
4、测试
public class TestDemo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
RegisteredSingleExample example1 = RegisteredSingleExample.getInstance(null);
Registered registered = Registered.getInstance();
System.out.println(example1+" "+registered);
RegisteredSingleExample re = new RegisteredSingleExample();
Map<String, RegisteredSingleExample> map = re.getMap();
System.out.println(map);
ExecutorService es=new ThreadPoolExecutor
(0,//核心线程池大小,只要有任务就会最少创建这么多线程来执行任务
200,//最大线程数
3000L, TimeUnit.SECONDS, //当线程数大于核心时,此为多于线程等待新任务的最长时间,超过时间便会死亡
new SynchronousQueue<>()//用来储存等待执行任务的线程
);
es.execute(new RunTest());
Thread thread = new RunTest2();
thread.start();
}
}
class RunTest implements Runnable{
@SneakyThrows
@Override
public void run() {
// Singleton instance = Singleton.getInstanceTwoCheck();
// HungryHanStyle instance = HungryHanStyle.getInstance();
RegisteredSingleExample instance = RegisteredSingleExample.getInstance(null);
System.out.println(instance);
}
}
class RunTest2 extends Thread{
@SneakyThrows
public void run() {
// Singleton instance = Singleton.getInstanceTwoCheck();
// HungryHanStyle instance = HungryHanStyle.getInstance();
RegisteredSingleExample instance = RegisteredSingleExample.getInstance(null);
System.out.println(instance);
}
}