不过时的技术

栏目: PHP · 发布时间: 6年前

内容简介:最近两天被极客时间的新课刷群刷屏。刷屏的标题大多是“学了这么多年 Java,却连 singleton 都不会用”、“面试总被问高并发,你真的会么”这一类标题党。内容千篇一律是推荐极客时间打新的课程,《Java 并发编程实战》。高并发哥又不是没做过,随手找了一下,发现陈皓在 2009 年的一篇文章就提到了正确的解法,以及背后的原因。《文中给出几种功能上正确的 singleton 写法。

最近两天被极客时间的新课刷群刷屏。刷屏的标题大多是“学了这么多年 Java,却连 singleton 都不会用”、“面试总被问高并发,你真的会么”这一类标题党。内容千篇一律是推荐极客时间打新的课程,《Java 并发编程实战》。

高并发哥又不是没做过,随手找了一下,发现陈皓在 2009 年的一篇文章就提到了正确的解法,以及背后的原因。《 深入浅出单实例 SINGLETON 设计模式 》。

文中给出几种功能上正确的 singleton 写法。

// version 1.4
public class Singleton {
    private volatile static Singleton singleton = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton== null) {
                    singleton= new Singleton();
                }
            }
        }
        return singleton;
    }
}

请留意私有变量的描述词 volatile ,目的是不让编译器对指令进行重 排序 优化。

// version 1.5
public class Singleton {
    private volatile static Singleton singleton = new Singleton();
    private Singleton()  {}
    public static Singleton getInstance() {
        return singleton;
    }
}

这是自动加载版本。每次加载类的时候,实例就生成了。所以加载类的过程可能会很慢(特别是有很多继承、引用的情况)。

// version 1.6
public class Singleton {
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton() {}
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

这是对上面 1.5 版本的修正。 SingletonHolder 是个私有类,并且在 Singleton 加载的时候才会被调用, INSTANCE 才会被真正创建。

这段代码是即确保了线程安全,又实现了懒加载的较优办法。

还有一个所谓最优(优雅?代码最少?)的办法,不过不建议大家使用,可读性实在不太高。有点奇技淫巧的意思,大大牺牲了代码的可读性。

public enum Singleton{
   INSTANCE;
}

利用了 enum 的创建是线程安全这一特性。

PS:PHP 中没有 singleton 的困扰,因为 php 语言特点决定的。php-fpm 本身就是 accepter-worker 并发模式,程序员写的 PHP 程序其实只是 worker,worker 与 worker 之间由 fpm 完成资源隔离和协调,PHP 程序员并不需要从内存数据的层面考虑并发的情况。所以有句话讲得不错, singleton 在 PHP 语言中不是一个好实践(practice) 。PHP 的 singleton 用简单的工厂模式就够了。

今天抽空找了下 MQTT 的 QoS2 实现方式,记录如下。原科普文链接《 MQTT QoS 深度解读 》。

无论是 QoS2 还是 transaction,原理都是一样的: 通过一次代价非常小、成功概率足够高的操作,作为最后确认的依据 。这样做并不是说绝对不出错,而是出错的概率足够低,实践中可以忽略。

sequenceDiagram
  participant Publisher
  participant Broker
  participant Subscriber
  Publisher->>Publisher: Store(Msg)
  Publisher->>Broker: PUBLISH(QoS2, Msg)
  Broker->>Broker: Store(Msg)
  Broker->>Publisher: PUBREC
  Publisher->>Broker: PUBREL
  Broker->>Subscriber: PUBLISH(QoS2, Msg)
  Broker->>Publisher: PUBCOMP
  Publisher->>Publisher: Delete(Msg)
  Subscriber->>Subscriber: Store(Msg)
  Subscriber->>Broker: PUBREC
  Broker->>Subscriber: PUBREL
  Subscriber->>Subscriber: Notify(Msg)
  Subscriber->>Broker: PUBCOMP
  Broker->>Broker: Delete(Msg)
  Subscriber->>Subscriber: Delete(Msg)

简单一点的模型,如果不需要中间的 broker,则流程如下。

sequenceDiagram
  participant Publisher
  participant Subscriber
  Publisher->>Publisher: Store(Msg)
  Publisher->>Subscriber: (1) PUBLISH(QoS2, Msg)
  Subscriber->>Subscriber: Store(Msg)
  Subscriber->>Publisher: (2) PUBREC
  Publisher->>Subscriber: (3) PUBREL
  Subscriber->>Subscriber: Notify(Msg)
  Subscriber->>Publisher: (4) PUBCOMP
  Subscriber->>Subscriber: Delete(Msg)
  Publisher->>Publisher: Delete(Msg)

从简化以后的模型可以看到,publisher 和 subscriber 有两次交互。第一次,publisher 把 msg 推送给 subscriber,对应 PUBLISH / PUBREC 指令。第二次,publisher 等于是询问 subscriber,“你是不是收到一次”,对应 PUBREL / PUBCOMP 指令。

如果没有第 (3)/(4)步, PUBREL / PUBCOMP 指令,实际就是 QoS1, 至少收到一次

再少一点,如果没有 (2)/(3)/(4) 步,只剩第 (1) 步,实际就是 QoS0, 至多只发送一次

科普文里面提问,为什么 MQTT QoS2 是两次“握手”,而不是像 TCP 一样,三次握手。我觉得这个问题太教条了。为什么 negotiate 就一定要想到 TCP 呢?当然,如果一定要回答,最本质的区别就是,MQTT QoS2 通讯是单向的,而 TCP 连接的通讯是双向的。单向的只需要一方取信于另外一方即可,而双向通讯需要两方都取信于对方。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Where Wizards Stay Up Late

Where Wizards Stay Up Late

Katie Hafner / Simon & Schuster / 1998-1-21 / USD 16.00

Twenty five years ago, it didn't exist. Today, twenty million people worldwide are surfing the Net. "Where Wizards Stay Up Late" is the exciting story of the pioneers responsible for creating the most......一起来看看 《Where Wizards Stay Up Late》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具