realpdai / tech-arch-doc-comments

Java 全栈知识体系 (留言区)
https://www.pdai.tech
MIT License
150 stars 42 forks source link

[Vssue]反馈问题 #5

Open realpdai opened 3 years ago

realpdai commented 3 years ago

https://www.pdai.tech/md/about/me/blog-question.html

heixiaozhi commented 2 years ago

作者你好,在项目 Springboot项目开发青铜哪里的项目代码都找不到了,github找不到该页面。

realpdai commented 2 years ago

@17365756283

作者你好,在项目 Springboot项目开发青铜哪里的项目代码都找不到了,github找不到该页面。

【项目】中整个章节都会重新整理下,引入更多优秀的学习资源,目前还在更新中,敬请期待。

目前学习SpringBoot项目可以参考SpringBoot 2.5.x 系列教程

andyRon commented 2 years ago

pdai,你好,你的网站太棒了,非常感谢。我发现spring有几个网页是空,不知道什么情况?比如: https://pdai.tech/md/spring/spring-x-framework-springmvc.html https://pdai.tech/md/spring/spring-x-framework-annotation.html https://pdai.tech/md/spring/spring-x-framework-spring5.html https://pdai.tech/md/spring/spring-x-framework-springmvc-source-1.html https://pdai.tech/md/spring/springboot/springboot-x-task-hashwheeltimer-timer.html

realpdai commented 2 years ago

pdai,你好,你的网站太棒了,非常感谢。我发现spring有几个网页是空,不知道什么情况?比如: https://pdai.tech/md/spring/spring-x-framework-springmvc.html https://pdai.tech/md/spring/spring-x-framework-annotation.html https://pdai.tech/md/spring/spring-x-framework-spring5.html https://pdai.tech/md/spring/spring-x-framework-springmvc-source-1.html https://pdai.tech/md/spring/springboot/springboot-x-task-hashwheeltimer-timer.html

相关文章还没有更新上去,近期会持续更新的~

JoeyHe912 commented 2 years ago

redis pubsub章节中 原文

发送信息到模式的工作也是由 PUBLISH 命令进行的, 显然就是匹配模式获得Channels,然后再把消息发给客户端。

实际上

PUBLISH 除了将 message 发送到所有订阅 channel 的客户端之外, 它还会将 channel 和 pubsub_patterns 中的模式进行对比, 如果 channel 和某个模式匹配的话, 那么也将 message 发送到订阅那个模式的客户端。

原文中的匹配模式获得Channels有点歧义,我理解实际上应该是publish时根据channel获得所有pattern以及对应的客户端

realpdai commented 2 years ago

@JoeyHe912

redis pubsub章节中 原文

发送信息到模式的工作也是由 PUBLISH 命令进行的, 显然就是匹配模式获得Channels,然后再把消息发给客户端。

实际上

PUBLISH 除了将 message 发送到所有订阅 channel 的客户端之外, 它还会将 channel 和 pubsub_patterns 中的模式进行对比, 如果 channel 和某个模式匹配的话, 那么也将 message 发送到订阅那个模式的客户端。

原文中的匹配模式获得Channels有点歧义,我理解实际上应该是publish时根据channel获得所有pattern以及对应的客户端

你好,不是太明白为何会有歧义:

原文 已经在上下文中对pubsub_patterns 数据结构进行了说明:

typedef struct pubsubPattern {
    redisClient *client;
    robj *pattern;
} pubsubPattern;

如下源码中,通过遍历整个 pubsub_patterns 链表,调用stringmatchlen方法来对pubsub_pattern(dictEntry *de就是pubsub_pattern)中的pattern进行模式匹配(过滤掉不满足的pattern的channel),通过addReplyPubsubPatMessage方法发送给再对pubsub_pattern中的client。

/*
 * Publish a message to all the subscribers.
 */
int pubsubPublishMessageInternal(robj *channel, robj *message, pubsubtype type) {
    int receivers = 0;
    dictEntry *de;
    dictIterator *di;
    listNode *ln;
    listIter li;

    /* Send to clients listening for that channel */
    de = dictFind(*type.serverPubSubChannels, channel);
    if (de) {
        list *list = dictGetVal(de);
        listNode *ln;
        listIter li;

        listRewind(list,&li);
        while ((ln = listNext(&li)) != NULL) {
            client *c = ln->value;
            addReplyPubsubMessage(c,channel,message);
            updateClientMemUsage(c);
            receivers++;
        }
    }

    if (type.shard) {
        /* Shard pubsub ignores patterns. */
        return receivers;
    }

    /* Send to clients listening to matching channels */
    di = dictGetIterator(server.pubsub_patterns);
    if (di) {
        channel = getDecodedObject(channel);
        while((de = dictNext(di)) != NULL) {
            robj *pattern = dictGetKey(de);
            list *clients = dictGetVal(de);
           // 模式匹配, 过滤掉不满足的pattern的channel
            if (!stringmatchlen((char*)pattern->ptr,
                                sdslen(pattern->ptr),
                                (char*)channel->ptr,
                                sdslen(channel->ptr),0)) continue;

            listRewind(clients,&li);
            while ((ln = listNext(&li)) != NULL) {
                client *c = listNodeValue(ln);
                addReplyPubsubPatMessage(c,pattern,channel,message);
                updateClientMemUsage(c);
                receivers++;
            }
        }
        decrRefCount(channel);
        dictReleaseIterator(di);
    }
    return receivers;
}

同时,为何pattern 还需要作为参数传入addReplyPubsubPatMessage?

因为这个pattern除了可以模式匹配channel外,还可以匹配message的内容。

/* Send a pubsub message of type "pmessage" to the client. The difference
 * with the "message" type delivered by addReplyPubsubMessage() is that
 * this message format also includes the pattern that matched the message. */
void addReplyPubsubPatMessage(client *c, robj *pat, robj *channel, robj *msg) {
    if (c->resp == 2)
        addReply(c,shared.mbulkhdr[4]);
    else
        addReplyPushLen(c,4);
    addReply(c,shared.pmessagebulk);
    addReplyBulk(c,pat);
    addReplyBulk(c,channel);
    addReplyBulk(c,msg);
}

再回看原文描述:

发送信息到模式的工作也是由 PUBLISH 命令进行的, 显然就是匹配模式获得Channels,然后再把消息发给客户端

基于上下文而言和源码,这里的模式匹配是指“pubsubPattern中的pattern”, 这里的客户端指“pubsubPattern中的client”。所以不认为有任何歧义~

JoeyHe912 commented 2 years ago

@realpdai channel不是PUBLISH命令的入参之一吗?为什么其中还会获得Channels(多个)呢? 源码看起来是拿入参的Channel,去跟链表里的所有pattern依次做匹配,获得匹配patterns对应的receivers 我比较纠结的是一次publish过程中应该只有一个channel?

刚开始深入学习redis,如果哪里不对还请继续指正。谢谢!

JoeyHe912 commented 2 years ago

https://pdai.tech/md/dev-spec/spec/dev-th-base.html

Soft state(软状态)软状态也称为弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据听不的过程存在延时。

一个typo:数据听不(同步)的过程存在延时

realpdai commented 2 years ago

@JoeyHe912

https://pdai.tech/md/dev-spec/spec/dev-th-base.html

Soft state(软状态)软状态也称为弱状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据听不的过程存在延时。

一个typo:数据听不(同步)的过程存在延时

感谢指出,已修复!

liusishan commented 2 years ago

作者你好,我在阅读中发现了文章中的文字可能存在的错误。 文章标题:Java 基础 - 反射机制详解 文章链接:https://pdai.tech/md/java/basic/java-basic-x-reflection.html 原文①:RRIT(Run-Time Type Identification)运行时类型识别。 ①这个地方的缩写应该是“RTTI”? 原文②:数组同样也被映射为为class 对象的一个类。 ②这句话里面“为”字重复

realpdai commented 2 years ago

@liusishan

作者你好,我在阅读中发现了文章中的文字可能存在的错误。 文章标题:Java 基础 - 反射机制详解 文章链接:https://pdai.tech/md/java/basic/java-basic-x-reflection.html 原文①:RRIT(Run-Time Type Identification)运行时类型识别。 ①这个地方的缩写应该是“RTTI”? 原文②:数组同样也被映射为为class 对象的一个类。 ②这句话里面“为”字重复

非常好的反馈格式!感谢指出,已经修复~

zhenpingliu commented 2 years ago

https://www.pdai.tech/md/java/thread/java-thread-x-lock-LockSupport.html --> Object.wait()和LockSupport.park()的区别 --> “如果在wait()之前执行了notify()会怎样? 抛出IllegalMonitorStateException异常;”

作者您好,这句话有点问题,如果在wait()之前调用notify()会怎样?程序应该会继续执行,但是wait会一直阻塞。 什么情况下抛出IllegalMonitorStateException异常呢?当前线程不是对象监视器的所有者时,调用nofify或者wait都会抛出此异常。

lsbnbdz commented 2 years ago

https://pdai.tech/md/java/thread/java-thread-x-juc-overview.html

文中第一个图,途中写的是aotmic,图的拼写有错误

cutehuman commented 2 years ago

文章链接: https://pdai.tech/md/db/nosql-redis/db-redis-data-types.html 错误: Redis 集合SMEMBER命令【使用】错误了。

realpdai commented 2 years ago

@zhenpingliu

https://www.pdai.tech/md/java/thread/java-thread-x-lock-LockSupport.html --> Object.wait()和LockSupport.park()的区别 --> “如果在wait()之前执行了notify()会怎样? 抛出IllegalMonitorStateException异常;”

作者您好,这句话有点问题,如果在wait()之前调用notify()会怎样?程序应该会继续执行,但是wait会一直阻塞。 什么情况下抛出IllegalMonitorStateException异常呢?当前线程不是对象监视器的所有者时,调用nofify或者wait都会抛出此异常。

很棒!已经更正!

realpdai commented 2 years ago

@lsbnbdz

https://pdai.tech/md/java/thread/java-thread-x-juc-overview.html

文中第一个图,途中写的是aotmic,图的拼写有错误

感谢指出,已经修复~

realpdai commented 2 years ago

@cutehuman

文章链接: https://pdai.tech/md/db/nosql-redis/db-redis-data-types.html 错误: Redis 集合SMEMBER命令【使用】错误了。

新版本是SMEMBERS,感谢指出,已经修复~

shoyu666 commented 2 years ago

https://pdai.tech/md/java/jvm/java-jvm-struct.html 图片裂了

realpdai commented 2 years ago

@shoyu666

https://pdai.tech/md/java/jvm/java-jvm-struct.html 图片裂了

我这边看没有问题哈

JoeyHe912 commented 2 years ago

https://pdai.tech/md/java/jvm/java-jvm-agent-arthas.html#%E9%87%8D%E8%A6%81%EF%BC%9A%E6%89%BE%E5%88%B0%E6%9C%80%E8%80%97%E6%97%B6%E7%9A%84%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8 重要:找到最耗时的方法调用? 这里是否应该是trace而不是stack?

realpdai commented 2 years ago

@JoeyHe912

https://pdai.tech/md/java/jvm/java-jvm-agent-arthas.html#%E9%87%8D%E8%A6%81%EF%BC%9A%E6%89%BE%E5%88%B0%E6%9C%80%E8%80%97%E6%97%B6%E7%9A%84%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8 重要:找到最耗时的方法调用? 这里是否应该是trace而不是stack?

很棒,笔误了,已经修正,感谢指出!

RoadTLife commented 2 years ago

地址: https://pdai.tech/md/dev-spec/spec/dev-th-acid.html
错误内容: 章节 什么是ACID。该词 Durablity(持久性)错误 ,请修改为 Durability(持久性)

realpdai commented 2 years ago

@RoadTLife

地址: https://pdai.tech/md/dev-spec/spec/dev-th-acid.html
错误内容: 章节 什么是ACID。该词 Durablity(持久性)错误 ,请修改为 Durability(持久性)

感谢,已修复这个typo.

j4free commented 2 years ago

作者您好, Java 基础 - 知识点 这部分 关于hashCode() 知识点的demo System.out.println(e1.equals(e2)); // true 这行代码返回false

j4free commented 2 years ago

@by111

作者您好, Java 基础 - 知识点 这部分 关于hashCode() 知识点的demo System.out.println(e1.equals(e2)); // true 这行代码返回false

对不起,没问题的 我没和上面的demo结合起来看

b1tzer commented 2 years ago

https://pdai.tech/md/algorithm/alg-sort-x-shell.html

希尔排序稳定性

希尔排序是不稳定的算法,它满足稳定算法的定义。 这句话前后矛盾。

realpdai commented 2 years ago

@b1tzer

https://pdai.tech/md/algorithm/alg-sort-x-shell.html

希尔排序稳定性

希尔排序是不稳定的算法,它满足稳定算法的定义。 这句话前后矛盾。

希尔排序不是稳定算法,它满足稳定算法的定义。少了一个不...

感谢指出,已经修正完善!

b1tzer commented 2 years ago

https://pdai.tech/md/java/java8/java8-jre.html 原文:

JPEDS工具使用

应为:

JDEPS工具使用

Dkenze commented 2 years ago

在Map - LinkedHashSet&Map源码解析中,描述的是java1.6中的源码,但java1.8中由于hashmap的修改,LinkdeHashMap的源码也做了响应修改。应指出文中叙述的是java1.6版本,或添加jav1.8解说。

Code-Lark commented 2 years ago

java中的Collection - LinkedList 源码解析 文章 链接:https://www.pdai.tech/md/java/collection/java-collection-LinkedList.html#removefirest-removelast-removee-removeindex 问题:标题出错removeFirest(), removeLast(), remove(e), remove(index) 应该是removeFirst()

b1tzer commented 2 years ago

https://pdai.tech/md/java/thread/java-thread-x-key-synchronized.html#%E9%94%81%E7%B2%97%E5%8C%96

锁消除

当然在实际开发中,我们很清楚的知道那些的方时线程独有的,不需要加同步锁,

锁粗化

示例使用 StringBuilder 不符合题意,该段旨在说明锁可以扩张,应用线程安全的 StringBuffer 举例

realpdai commented 2 years ago

@b1tzer

https://pdai.tech/md/java/java8/java8-jre.html 原文:

JPEDS工具使用

应为:

JDEPS工具使用

感谢指出,已经修正!

realpdai commented 2 years ago

@Code-Lark

java中的Collection - LinkedList 源码解析 文章 链接:https://www.pdai.tech/md/java/collection/java-collection-LinkedList.html#removefirest-removelast-removee-removeindex 问题:标题出错removeFirest(), removeLast(), remove(e), remove(index) 应该是removeFirst()

感谢指出,已经修正!

realpdai commented 2 years ago

@b1tzer

https://pdai.tech/md/java/thread/java-thread-x-key-synchronized.html#%E9%94%81%E7%B2%97%E5%8C%96

锁消除

当然在实际开发中,我们很清楚的知道那些的方时线程独有的,不需要加同步锁,

锁粗化

示例使用 StringBuilder 不符合题意,该段旨在说明锁可以扩张,应用线程安全的 StringBuffer 举例

感谢支持,已经修正!

b1tzer commented 2 years ago

https://pdai.tech/md/arch/arch-x-overview.html

D 分层下看架构技术点

图片中 CND 应为 CDN

https://pdai.tech/md/java/jvm/java-jvm-class.html

Class文件的结构属性

图片中方法表属性对应的解释有错别字。与字段表类型与字段表类似

https://pdai.tech/md/java/jvm/java-jvm-class.html

方法表集合

code内的主要属性为: xxxxxxxxxx

https://pdai.tech/md/java/jvm/java-jvm-gc.html

3. Parallel Scavenge 收集器

最后一段 可以通过一个开关参数打卡 GC 自适应的调节策略(GC Ergonomics),就不需要手工指定新生代的大小(-Xmn)

JoeyHe912 commented 2 years ago

https://pdai.tech/md/java/thread/java-thread-x-lock-AbstractQueuedSynchronizer.html#aqs-%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3

说明: 经过一系列的方法调用,最后达到的状态是禁用t2线程,因为调用了LockSupport.lock。

实际上应该是LockSupport.park

realpdai commented 2 years ago

@b1tzer

https://pdai.tech/md/arch/arch-x-overview.html

D 分层下看架构技术点

图片中 CND 应为 CDN

https://pdai.tech/md/java/jvm/java-jvm-class.html

Class文件的结构属性

图片中方法表属性对应的解释有错别字。与字段表类型与字段表类似

https://pdai.tech/md/java/jvm/java-jvm-class.html

方法表集合

code内的主要属性为: xxxxxxxxxx

  • attribute_info: xxxxxx 注释里的"java/lang/Object.""😦)V"

https://pdai.tech/md/java/jvm/java-jvm-gc.html

3. Parallel Scavenge 收集器

最后一段 可以通过一个开关参数打卡 GC 自适应的调节策略(GC Ergonomics),就不需要手工指定新生代的大小(-Xmn)

感谢指出,已经修正。

realpdai commented 2 years ago

@JoeyHe912

https://pdai.tech/md/java/thread/java-thread-x-lock-AbstractQueuedSynchronizer.html#aqs-%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3

说明: 经过一系列的方法调用,最后达到的状态是禁用t2线程,因为调用了LockSupport.lock。

实际上应该是LockSupport.park

感谢指出,已经修正!

readyhuihui commented 2 years ago

文章标题:“关键字:final详解” 文章链接:https://www.pdai.tech/md/java/thread/java-thread-x-key-final.html#%E4%BF%AE%E9%A5%B0%E5%8F%98%E9%87%8F 问题概述:在介绍“blank final”的时候,文章有这样一句话“可以看到i2的赋值更为灵活。但是请注意,如果字段由static和final修饰,仅能在定义处赋值,因为该字段不属于对象,属于这个类”。 这里的“仅能在定义处赋值”建议改成:“仅能在声明时赋值或声明后在静态代码块中赋值”。

oahnukuw commented 2 years ago

https://pdai.tech/md/framework/tomcat/tomcat-x-design-web-container.html#%E5%9F%BA%E7%A1%80%E8%AE%A4%E7%9F%A5%EF%BC%9A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E4%BA%A4%E4%BA%92

原文: 客户端和服务器端之间的交互式通过Socket来实现的,它术语应用层的协议。 【它术语应用层的协议】-> 【它属于应用层的协议】?

Phukety commented 2 years ago

作者您好,您的文章写的很全很详细,很感谢您分享这么多有用的资料。但我最近在学习的时候,发现(可能)有一个小问题(如果不是问题的话,麻烦作者忽略,不好意思),详情如下: 原文位置:https://www.pdai.tech/md/java/thread/java-thread-x-key-synchronized.html#%E5%8F%AF%E9%87%8D%E5%85%A5%E5%8E%9F%E7%90%86%EF%BC%9A%E5%8A%A0%E9%94%81%E6%AC%A1%E6%95%B0%E8%AE%A1%E6%95%B0%E5%99%A8 背景:

// 作者的上下文代码
public class SynchronizedDemo2 {

    Object object = new Object();
    public void method1() {
        synchronized (object) {

        }
        method2();
    }

    private static void method2() {

    }
}

原话: “上面的demo中在执行完同步代码块之后紧接着再会去执行一个静态同步方法,而这个方法锁的对象依然就这个类对象,那么这个正在执行的线程还需要获取该锁吗? 答案是不必的,从上图中就可以看出来,执行静态同步方法的时候就只有一条monitorexit指令,并没有monitorenter获取锁的指令。这就是锁的重入性,即在同一锁程中,线程不需要再次获取同一把锁。”

可能存在的问题:

  1. method2方法并不是静态同步方法,而是普通的静态方法
  2. 该静态方法的锁是类class而不是method1的object对象锁,所以两者并不是同一把锁
  3. 我自己试着将method2方法删除,重新查看字节码,发现依然有一个monitorenter和两个monitorexit,和原来一样,说明和锁的重入性无关。经上网查询,好像第二个monitorexit只是退出方法时为了确保锁已释放才加的( Be sure to exit the monitor)
    // 文章来源 https://blog.csdn.net/doctor_who2004/article/details/104508354
    Method void onlyMe(Foo)
    0   aload_1             // Push f
    1   dup                 // Duplicate it on the stack
    2   astore_2            // Store duplicate in local variable 2
    3   monitorenter        // Enter the monitor associated with f
    4   aload_0             // Holding the monitor, pass this and...
    5   invokevirtual #5    // ...call Example.doSomething()V
    8   aload_2             // Push local variable 2 (f)
    9   monitorexit         // Exit the monitor associated with f
    10  goto 18             // Complete the method normally
    13  astore_3            // In case of any throw, end up here
    14  aload_2             // Push local variable 2 (f)
    15  monitorexit         // Be sure to exit the monitor!
    16  aload_3             // Push thrown value...
    17  athrow              // ...and rethrow value to the invoker
    18  return              // Return in the normal case
    Exception table:
    From    To      Target      Type
    4       10      13          any
    13      16      13          any

    感谢!

realpdai commented 2 years ago

@readyhuihui

文章标题:“关键字:final详解” 文章链接:https://www.pdai.tech/md/java/thread/java-thread-x-key-final.html#%E4%BF%AE%E9%A5%B0%E5%8F%98%E9%87%8F 问题概述:在介绍“blank final”的时候,文章有这样一句话“可以看到i2的赋值更为灵活。但是请注意,如果字段由static和final修饰,仅能在定义处赋值,因为该字段不属于对象,属于这个类”。 这里的“仅能在定义处赋值”建议改成:“仅能在声明时赋值或声明后在静态代码块中赋值”。

感谢你的建议,这样表述更好一些,已更新!

realpdai commented 2 years ago

@homemu

https://pdai.tech/md/framework/tomcat/tomcat-x-design-web-container.html#%E5%9F%BA%E7%A1%80%E8%AE%A4%E7%9F%A5%EF%BC%9A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E4%BA%A4%E4%BA%92

原文: 客户端和服务器端之间的交互式通过Socket来实现的,它术语应用层的协议。 【它术语应用层的协议】-> 【它属于应用层的协议】?

感谢指出,已经更正!

realpdai commented 2 years ago

@Phukety

作者您好,您的文章写的很全很详细,很感谢您分享这么多有用的资料。但我最近在学习的时候,发现(可能)有一个小问题(如果不是问题的话,麻烦作者忽略,不好意思),详情如下: 原文位置:https://www.pdai.tech/md/java/thread/java-thread-x-key-synchronized.html#%E5%8F%AF%E9%87%8D%E5%85%A5%E5%8E%9F%E7%90%86%EF%BC%9A%E5%8A%A0%E9%94%81%E6%AC%A1%E6%95%B0%E8%AE%A1%E6%95%B0%E5%99%A8 背景:

// 作者的上下文代码
public class SynchronizedDemo2 {

    Object object = new Object();
    public void method1() {
        synchronized (object) {

        }
        method2();
    }

    private static void method2() {

    }
}

原话: “上面的demo中在执行完同步代码块之后紧接着再会去执行一个静态同步方法,而这个方法锁的对象依然就这个类对象,那么这个正在执行的线程还需要获取该锁吗? 答案是不必的,从上图中就可以看出来,执行静态同步方法的时候就只有一条monitorexit指令,并没有monitorenter获取锁的指令。这就是锁的重入性,即在同一锁程中,线程不需要再次获取同一把锁。”

可能存在的问题:

  1. method2方法并不是静态同步方法,而是普通的静态方法
  2. 该静态方法的锁是类class而不是method1的object对象锁,所以两者并不是同一把锁
  3. 我自己试着将method2方法删除,重新查看字节码,发现依然有一个monitorenter和两个monitorexit,和原来一样,说明和锁的重入性无关。经上网查询,好像第二个monitorexit只是退出方法时为了确保锁已释放才加的( Be sure to exit the monitor)
    // 文章来源 https://blog.csdn.net/doctor_who2004/article/details/104508354
    Method void onlyMe(Foo)
    0   aload_1             // Push f
    1   dup                 // Duplicate it on the stack
    2   astore_2            // Store duplicate in local variable 2
    3   monitorenter        // Enter the monitor associated with f
    4   aload_0             // Holding the monitor, pass this and...
    5   invokevirtual #5    // ...call Example.doSomething()V
    8   aload_2             // Push local variable 2 (f)
    9   monitorexit         // Exit the monitor associated with f
    10  goto 18             // Complete the method normally
    13  astore_3            // In case of any throw, end up here
    14  aload_2             // Push local variable 2 (f)
    15  monitorexit         // Be sure to exit the monitor!
    16  aload_3             // Push thrown value...
    17  athrow              // ...and rethrow value to the invoker
    18  return              // Return in the normal case
    Exception table:
    From    To      Target      Type
    4       10      13          any
    13      16      13          any

    感谢!

看的很仔细,这里的Demo代码应该是如下,(漏了,已经在原文中补充)

public class SynchronizedDemo {

    public static void main(String[] args) {
        synchronized (SynchronizedDemo.class) {

        }
        method2();
    }

    private synchronized static void method2() {

    }
}

这里有两个monitorexit并不是执行两次monitorexit,需要看Exception table,正常情况monitorexit后直接goto到后续行了,异常情况才进入第二个monitorexit确保关闭的。

zhoumaogen commented 2 years ago

你好,在 设计模式-构造器模式参考链接指向错误,指向了抽象工厂模式

realpdai commented 2 years ago

@MecanZhou

你好,在 设计模式-构造器模式参考链接指向错误,指向了抽象工厂模式

感谢指出,已经修正

dby321 commented 2 years ago

Java并发-线程基础: 线程的实现方法 【补充】Executors.和new ThreadPoolExecutor也可以实现线程 await() signal() signalAll() 【疑问】原文:相比于 wait() 这种等待方式,await() 可以指定等待的条件,因此更加灵活。

realpdai commented 2 years ago

Java并发-线程基础: 线程的实现方法 【补充】Executors.和new ThreadPoolExecutor也可以实现线程 await() signal() signalAll() 【疑问】原文:相比于 wait() 这种等待方式,await() 可以指定等待的条件,因此更加灵活。

没有问题

JoeyHe912 commented 2 years ago

https://pdai.tech/md/db/nosql-redis/db-redis-data-types.html#zset%E6%9C%89%E5%BA%8F%E9%9B%86%E5%90%88

有序集合的成员是唯一的,但分数(score)却可以重复。【集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。】 方括号中的内容在这里好像不太对

LegendSunshine commented 2 years ago

HashSet不是基于HashMap实现的吗