《从Java面试题看源码》-Java11中的toString与Java8的区别

简介: 《从Java面试题看源码》-Java11中的toString与Java8的区别

​​在这里插入图片描述
在前面【《从Java面试题来看源码》-LinkedBlockingQueue 源码分析】的文章中,我们看到有一个toString方法是这样的:

public String toString() {
    //
    return Helpers.collectionToString(this);
}

为什么要这样呢?

分析

`使用Helpers类,来输出字符串,与Java8不同。
Helpers类用于并发包输出字符串,该类只在输出数组的时候获取锁,而不是在toString中获取锁`

Java11中用到了Helpers.collectionToString(this)的方式输出字符串,并且与Java8是不同的。

先看看Java11中Helpers类的写法:

 /**
     * Collection.toString() 的一种实现,适用于有锁的类。
     * 代替了以前在整个toString()过程中加锁,或者在每次调用Iterator.next()的时候加锁
     * 该方法只在调用toArray()期间加锁,以减少其他线程对访问集合时产生的影响
     * 并且遵循在加锁期间,不调用任何外部代码
     */
static String collectionToString(Collection<?> c) {
    //这里toArray会加锁
    final Object[] a = c.toArray();
    final int size = a.length;
    if (size == 0)
        return "[]";
    int charLength = 0;

    // Replace every array element with its string representation
    for (int i = 0; i < size; i++) {
        Object e = a[i];
        // Extreme compatibility with AbstractCollection.toString()
        String s = (e == c) ? "(this Collection)" : objectToString(e);
        a[i] = s;
        charLength += s.length();
    }

    return toString(a, size, charLength);
}

/**
 * 与 Arrays.toString() 类似,但调用者保证 size > 0,索引为 0 <= i < size 的每
 * 个元素都是非空 String,charLength 是输入 String 的长度之和。
 */
static String toString(Object[] a, int size, int charLength) {
    // assert a != null;
    // assert size > 0;

    // Copy each string into a perfectly sized char[]
    // Length of [ , , , ] == 2 * size
    final char[] chars = new char[charLength + 2 * size];
    chars[0] = '[';
    int j = 1;
    for (int i = 0; i < size; i++) {
        if (i > 0) {
            chars[j++] = ',';
            chars[j++] = ' ';
        }
        String s = (String) a[i];
        int len = s.length();
        s.getChars(0, len, chars, j);
        j += len;
    }
    chars[j] = ']';
    // assert j == chars.length - 1;
    return new String(chars);
}

整个过程中就是将当前状态队列的元素进行拼接输出,而不会影响到其他线程操作队列,只是在通过toArray()获取队列元素的时候进行加锁。

看看Java8是怎么写的:

public String toString() {
    fullyLock();
    try {
        Node<E> p = head.next;
        if (p == null)
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = p.item;
            sb.append(e == this ? "(this Collection)" : e);
            p = p.next;
            if (p == null)
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    } finally {
        fullyUnlock();
    }
}

Java8中,toString输出字符串在前面加了一个锁fullyLock(),fullyLock()使用ReentrantLock对put和take、poll分别加锁。

Java8会在整个toString的拼接过程中,对队列进行加锁,会影响性能。

private final ReentrantLock takeLock = new ReentrantLock();
private final ReentrantLock putLock = new ReentrantLock();
void fullyLock() {
    putLock.lock();
    takeLock.lock();
}

总结

简单点说

Java8中的toString,就如同一个人干活,一群人歇下来看着他干完完,比较粗暴。
在这里插入图片描述
Java11中是:

toString():我要输出了,队列你先把当前值给我

队列:放下原来的事,把toString()要的数据准备好,给了toString()后,继续做原来的事

toString:我可以输出了
在这里插入图片描述
我想这应该是很好理解的。

相关文章
|
1天前
|
存储 Java
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
43 23
|
1天前
|
Java 关系型数据库 MySQL
java+B/S架构医院绩效考核管理系统源码 医院绩效管理系统4大特点
医院绩效考核管理系统,采用多维度综合绩效考核的形式,针对院内实际情况分别对工作量、KPI指标、科研、教学、管理等进行全面考核。医院可结合实际需求,对考核方案中各维度进行灵活配置,对各维度的权重、衡量标准、数据统计方式进行自定义维护。
10 0
|
1天前
|
设计模式 API 数据格式
腾讯面试官问我适配器和桥接器的区别?
腾讯面试官问我适配器和桥接器的区别?
7 0
|
1天前
|
消息中间件 安全 前端开发
字节面试:说说Java中的锁机制?
Java 中的锁(Locking)机制主要是为了解决多线程环境下,对共享资源并发访问时的同步和互斥控制,以确保共享资源的安全访问。 锁的作用主要体现在以下几个方面: 1. **互斥访问**:确保在任何时刻,只有一个线程能够访问特定的资源或执行特定的代码段。这防止了多个线程同时修改同一资源导致的数据不一致问题。 2. **内存可见性**:通过锁的获取和释放,可以确保在锁保护的代码块中对共享变量的修改对其他线程可见。这是因为 Java 内存模型(JMM)规定,对锁的释放会把修改过的共享变量从线程的工作内存刷新到主内存中,而获取锁时会从主内存中读取最新的共享变量值。 3. **保证原子性**:锁
16 1
|
1天前
|
Java 数据挖掘 BI
Java医院绩效考核系统源码B/S+avue+MySQL助力医院实现精细化管理
医院绩效考核系统目标是实现对科室、病区财务指标、客户指标、流程指标、成长指标的全面考核、分析,并与奖金分配、学科建设水平评价挂钩。
30 0
|
1天前
|
数据采集 前端开发 Java
Java医院绩效考核系统源码maven+Visual Studio Code一体化人力资源saas平台系统源码
医院绩效解决方案包括医院绩效管理(BSC)、综合奖金核算(RBRVS),涵盖从绩效方案的咨询与定制、数据采集、绩效考核及反馈、绩效奖金核算到科到组、分配到员工个人全流程绩效管理;将医院、科室、医护人员利益绑定;全面激活人才活力;兼顾质量和效益、长期与短期利益;助力医院降本增效,持续改善、优化收入、成本结构。
15 0
|
1天前
|
监控 前端开发 Java
Java基于B/S医院绩效考核管理平台系统源码 医院智慧绩效管理系统源码
医院绩效考核系统是一个关键的管理工具,旨在评估和优化医院内部各部门、科室和员工的绩效。一个有效的绩效考核系统不仅能帮助医院实现其战略目标,还能提升医疗服务质量,增强患者满意度,并促进员工的专业成长
19 0
|
1天前
|
Java 云计算
Java智能区域医院云HIS系统SaaS源码
云HIS提供标准化、信息化、可共享的医疗信息管理系统,实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。优化就医、管理流程,提升患者满意度、基层首诊率,通过信息共享、辅助诊疗等手段,提高基层医生的服务能力构建和谐的基层医患关系。
36 2
|
1天前
|
Java
从源码出发:JAVA中对象的比较
从源码出发:JAVA中对象的比较
19 3
|
1天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
21 0