设计模式【加锁懒汉单例】,并发我很自信

159 阅读2分钟

前言

  • 入门开发其实是很简单的,尤其对于中高级开发来说学习掌握一门语言只是语法的事情。因为他们掌握了语法之后就可以借助通用的设计模式思想来结构化自己的代码。今天我们开辟一个新章节就是设计模式。设计模式是不针对具体某种语言他是代码层面的设计。

测试

public static void main(String[] args)
{
    System.out.println("获取第一个Person类:");
    Person person1=SingleFactory.getInstance();
    System.out.println(person1.toString());
    System.out.println("**************************");
    System.out.println("获取第二个Person类:");
    Person person2=SingleFactory.getInstance();
    System.out.println(person2.toString());
}
  • 这个是我们非线程安全的懒汉式单例模式加载。上文我们也有提到在多线程下这种单例是不安全的。

多线程测试

public class clientThread extends Thread
{
​
    @Override
    public void run()
    {
        System.out.println(SingleFactory.getIstance().toString());
    }
​
    public static void main(String[] args)
    {
        clientThread[] clients = new clientThread[10];
        for (int i = 0; i < clients.length; i++)
        {
            clients[i] = new clientThread();
        }
        for (int i = 0; i < clients.length; i++)
        {
            clients[i].start();
        }
    }
}
  • 诺,如果我们新建10个线程去测试的话就有可能出现不安全的问题。如果10个太少的话你可以设置更多的线程。总之在并发达到一定程度时肯定回出现单例模式中会出现两个设置以上不同的实例出现的。

如何解决

  • 出现问题肯定回油解决方案的。那么该如何解决呢?首先我们已经明确问题所在就是多线程导致创建对象时出现重复
if (person == null)
{
    person = new Person();
}
  • 也就是说A线程执行了if并且person为null ,还没有执行new Person时 ,就被切换到B线程,此时B线程也判断if 且person==null .
  • 最终AB线程都执行到if里,这个时候就会出现创建两个Person对象
  • 既然是这块代码出现问题,那么我们只需要在这块代码上加上锁就可以了
synchronized (SingleFactory.class)
{
    if (person == null)
    {
        person = new Person();
    }
}
  • 这里需要注意一下的事,我们不要在整个方法上加,因为方法里可能还会有其他的业务处理。所以我们将锁加在最关键的地方。

总结

  • 在并发场景下此种懒汉模式单例还是很推荐大家使用的。