设计模式(自学)

设计模式

    • 1. 单例模式_饿汉式(静态常量)
    • 2. 单例模式_饿汉式(静态代码块)
    • 3. 单例模式_懒汉式
    • 4. 单例模式_懒汉式(线程安全,同步方法)
    • 5. 单例模式_懒汉式(线程安全,同步代码块)
    • 6. 单例模式_懒汉式(线程安全,双重检查)
    • 7. 单例模式(静态内部类)
    • 8. 单例模式_懒汉式(枚举)
    • 9. 多态举例
    • 10.死锁举例

1. 单例模式_饿汉式(静态常量)

//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部不能new
    private Singleton() {

    }
    //2.本类内部创建对象实例
    private static final Singleton INSTANCE = new Singleton();
    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        return INSTANCE ;
    }
}

2. 单例模式_饿汉式(静态代码块)

//饿汉式(静态代码块)
class Singleton {
    //1. 构造器私有化, 外部不能new
    private Singleton() {
    }
    //2.本类内部创建对象实例
    private static Singleton instance;
    static { // 在静态代码块中,创建单例对象
        instance = new Singleton();
    }
    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
}

3. 单例模式_懒汉式

//懒汉式
class Singleton {
    private static Singleton instance;
    private Singleton() {}
    //提供一个静态的公有方法,当使用到该方法时,才去创建 instance
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

4. 单例模式_懒汉式(线程安全,同步方法)

// 懒汉式(线程安全,同步方法)
class Singleton {
    private static Singleton instance;
    private Singleton() {}
    //提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
    //即懒汉式
    public static synchronized Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

5. 单例模式_懒汉式(线程安全,同步代码块)

// 懒汉式(线程安全,同步代码块)
class Singleton {
    private static Singleton instance;
    private Singleton() {}
    //提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
    //即懒汉式
    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (Singleton.class){
                instance = new Singleton();
            }
        }
        return instance;
    }
}

6. 单例模式_懒汉式(线程安全,双重检查)

// 懒汉式(双重检查)
class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    //提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
    //同时保证了效率, 推荐使用
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }

        }
        return instance;
    }
}

7. 单例模式(静态内部类)

// 静态内部类完成, 推荐使用
class Singleton {
    //构造器私有化
    private Singleton() {}
    //写一个静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }
    //提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
    public static synchronized Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

8. 单例模式_懒汉式(枚举)

// 使用枚举,可以实现单例, 推荐
enum Singleton {
    INSTANCE; //属性
}

9. 多态举例

没有使用多态

public class Main{
    public static void main(String[] args) {
        Dog dog = new Dog();
        feed(dog);
        Cat cat = new Cat();
        feed(cat);
    }

    public static void feed(Dog dog){
        dog.eat();
    }

    public static void feed(Cat cat){
        cat.eat();
    }
}

class Dog{
    public void eat(){
        System.out.println("dog吃");
    }
}

class Cat{
    public void eat(){
        System.out.println("cat吃");
    }
}

使用多态

public class Main{
    public static void main(String[] args) {
        Dog dog = new Dog();
        feed(dog);
        Cat cat = new Cat();
        feed(cat);
    }

    public static void feed(Animal a){
        a.eat();
    }
}

abstract class Animal{
    abstract void eat();
}

class Dog extends Animal{
    public void eat(){
        System.out.println("dog吃");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("cat吃");
    }
}

10.死锁举例

场景:女孩化妆,需要使用口红和镜子
定义两个女孩,一个先拿口红再拿镜子,一个先拿镜子再拿口红,形成死锁;

public class Main {
    public static void main(String[] args) {
        Gril girl1 = new Gril(0, "小红");
        Gril girl2 = new Gril(1, "小芳");
        new Thread(girl1).start();
        new Thread(girl2).start();
    }
}
//口红类
class Lipstick {
}
//镜子类
class Mirror {
}

class Gril implements Runnable  {
    private Lipstick lipstick = new Lipstick();
    private Mirror mirror = new Mirror();

    private int choice;
    private String girlName;

    public Gril(int choice, String girlName) {
        this.choice = choice;
        this.girlName = girlName;
    }

    @Override
    public void run() {
        try {
            makeUp();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void makeUp() throws InterruptedException {
    	// 如果选择为0,先拿口红,再拿镜子,尝试拿镜子的时候不释放口红
        if (choice == 0) {
            synchronized (Lipstick.class) {
                System.out.println(this.girlName + "拿口红");
                Thread.sleep(1000);
                synchronized (Mirror.class) {
                    System.out.println(this.girlName + "拿镜子");
                }
            }
        } else { // 如果选择不为0,先拿镜子,再拿口红,尝试拿口红的时候不释放镜子
            synchronized (Mirror.class) {
                System.out.println(this.girlName + "拿镜子");
                Thread.sleep(2000);
                synchronized (Lipstick.class) {
                    System.out.println(this.girlName + "拿口红");
                }
            }
        }
    }
}

如何解决死锁:在想拿到另一件东西之前释放之前手里有的东西;

public void makeUp() throws InterruptedException {
        if (choice == 0) {
            synchronized (Lipstick.class) {
                System.out.println(this.girlName + "拿口红");
            }
            Thread.sleep(1000);
            synchronized (Mirror.class) {
                System.out.println(this.girlName + "拿镜子");
            }
        } else {
            synchronized (Mirror.class) {
                System.out.println(this.girlName + "拿镜子");
            }
            Thread.sleep(2000);
            synchronized (Lipstick.class) {
                System.out.println(this.girlName + "拿口红");
            }
        }
    }

你可能感兴趣的:(力扣刷题,设计模式,单例模式,java)