设计模式简介

1、单例模式

1.1、饿汉式

类加载到内存后,就实例化一个单例,JVM保证了线程安全。

唯一缺点:不管用到与否,类加载时就完成实例化了。

写法1
public class Singleton01 {
    
    private static final Singleton01 INSTANCE = new Singleton01();

    public static Singleton01 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton01 s1 = Singleton01.getInstance();
        Singleton01 s2 = Singleton01.getInstance();
        System.out.println(s1 == s2);
    }
}
写法2
public class Singleton02 {

    private static final Singleton02 INSTANCE;
    
    static {
        INSTANCE = new Singleton02();
    }

    public static Singleton02 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton02 s1 = Singleton02.getInstance();
        Singleton02 s2 = Singleton02.getInstance();
        System.out.println(s1 == s2);
    }
}

1.2、懒汉式

实现了lazy loading,但是却带来了线程不安全。

public class Singleton03 {

    private static Singleton03 INSTANCE;

    private Singleton03() {

    }

    public static Singleton03 getInstance(){
        if(INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Singleton03();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(
                    () -> System.out.println(Singleton03.getInstance())
            ).start();
        }
    }
}

运行结果:

在这里插入图片描述

1.3、懒汉式(线程安全)

获取实例的方法加入synchronized,虽然解决了线程安全问题,但是效率下降了。

1.3.1、synchronized修饰方法
public class Singleton04 {

    private static Singleton04 INSTANCE;

    private Singleton04() {

    }

    public static synchronized Singleton04 getInstance(){
        if(INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Singleton04();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(
                    () -> System.out.println(Singleton04.getInstance())
            ).start();
        }
    }
}
1.3.2、synchronized修饰代码块
public class Singleton05 {

    private static Singleton05 INSTANCE;

    private Singleton05() {

    }

    public static Singleton05 getInstance() {
        if(INSTANCE == null) {
            //修饰代码块
            synchronized (Singleton05.class) {
                //需要双重检查,不然会线程不安全
                if (INSTANCE == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Singleton05();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(
                    () -> System.out.println(Singleton05.getInstance())
            ).start();
        }
    }
}

1.4、静态内部类方式

JVM保证单例

加载外部类时不会加载内部类,这样可以实现懒加载

public class Singleton06 {

    private Singleton06() {

    }

    private static class Singleton06Holder {
        private final static Singleton06 INSTANCE = new Singleton06();
    }

    public static Singleton06 getInstance(){
        return Singleton06Holder.INSTANCE;
    }
    
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(
                    () -> System.out.println(Singleton06.getInstance())
            ).start();
        }
    }
}

1.5、枚举方式

不仅可以解决线程同步问题,还可以防止反序列化

public enum Singleton07 {

    INSTANCE;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(
                    () -> System.out.println(Singleton07.INSTANCE.hashCode())
            ).start();
        }
    }
}

2、策略模式

定义一系列算法,将每一个算法封装起来,并使它们可以互相替换。策略算法让算法可以独立于使用它的客户端而变化。

Sorter需要一个比较方法,调用方可以根据不同的策略选择不同的comparator。

关系图

在这里插入图片描述

代码实现

Sorter.java
public class Sorter<T> {

    public void sort(T[] arr, Comparator<T> comparator) {
        for (int i = 0; i < arr.length - 1; i++){
            int minPos = i;
            for(int j = i + 1; j < arr.length; j++){
                minPos = comparator.compare(arr[j], arr[minPos]) == -1 ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }
    void swap(T[] arr, int i, int j){
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
Comparator.java
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}
DogComparator.java
public class DogComparator implements Comparator<Dog>{

    @Override
    public int compare(Dog o1, Dog o2) {
        if(o1.food > o2.food) return 1;
        else if(o1.food < o2.food) return -1;
        return 0;
    }
}
CatComparator.java
public class CatComparator implements Comparator<Cat>{

    @Override
    public int compare(Cat o1, Cat o2) {
        if(o1.weight * o1.height > o2.weight * o2.height) return 1;
        else if(o1.weight * o1.height < o2.weight * o2.height) return -1;
        return 0;
    }
}
Dog.java
public class Dog{
    int food;

    public Dog(int food) {
        this.food = food;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "food=" + food +
                '}';
    }
}
Cat.java
public class Cat {
    int weight, height;

    public Cat(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "weight=" + weight +
                ", height=" + height +
                '}';
    }
}
Main.java
public class Main {

    public static void main(String[] args) {

        Sorter<Dog> dogSorter = new Sorter<>();
        Dog[] dogs = {new Dog(3), new Dog(5), new Dog(1)};
        dogSorter.sort(dogs, new DogComparator());
        System.out.println(Arrays.toString(dogs));

        Sorter<Cat> catSorter = new Sorter<>();
        Cat[] cats = {new Cat(3, 3), new Cat(2, 4), new Cat(3, 4)};
        catSorter.sort(cats, new CatComparator());
        System.out.println(Arrays.toString(cats));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值