Java-单例模式

58 阅读1分钟
  • 单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。

/**
 * 单例模式
 * 饿汉式
 */
class Bank {

    private static Bank bank=new Bank();

    private Bank(){

    }

    public static Bank getBank() throws InterruptedException {
        Thread.sleep(1000);
        return bank;
    }
}

/**
 * 单例模式
 * 懒汉式
 */
class GirlFriend{
   private static volatile GirlFriend  girlFriend;

   private GirlFriend(){

   }

    public static GirlFriend getGirlFriend() throws InterruptedException {
        //if 优化判空效率 得加volatile  不让 创造对象指令重排 拿到没有初始化好的对象
        if (girlFriend == null) {
            //线程不安全 不加同步锁 同时进行可能出现不同对象
            synchronized (GirlFriend.class) {
                if(girlFriend==null){
                    //让多对象问题 出现更明显
                    Thread.sleep(1000);
                    girlFriend = new GirlFriend();
                }
            }
        }
        return girlFriend;
    }
}

/**
 * @author 小乌龟
 */
public  class Teacher {

    public static void main(String[] args) {
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                try {
                    Bank bank = Bank.getBank();
                    GirlFriend girlFriend = GirlFriend.getGirlFriend();
                    System.out.println("一号线程" + girlFriend.toString());
                    System.out.println("一号线程" + bank.toString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                try {
                    Bank bank = Bank.getBank();
                    GirlFriend girlFriend = GirlFriend.getGirlFriend();
                    System.out.println("二号线程" + girlFriend.toString());
                    System.out.println("二号线程" + bank.toString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        new Thread(runnable1).start();
        new Thread(runnable2).start();

    }
}

image.png