Java 基础知识点


前言

一、string,StringBuffer,StringBuilder 的区别

String是不可变类,每当我们对String进行操作的时候,总是会创建新的字符串。操作String很耗资源,所以Java提供了两个工具类来操作String - StringBuffer和StringBuilder。

线程安全:StringBuffer:线程安全,StringBuilder:线程不安全。因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 并没有修饰。

缓冲区:StringBuffer 每次获取 toString 都会直接使用缓存区的 toStringCache 值来构造一个字符串。而 StringBuilder 则每次都需要复制一次字符数组,再构造一个字符串。

性能:StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,因为那维护同步数据的正确性肯定要消耗资源的,所以毫无疑问,StringBuilder 的性能要远大于 StringBuffer。

StringBuffer 的append 方式,是通过String.getChars 方法拷贝的。该方法的作用是将当前字符串从start到end-1位置上的字符复制到字符数组c中,并从c的offset处开始存放

所以,StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景,如果是确定线程安全单线程场合 StringBuilder 更适合。

String类代表字符串,字符串是常量,常量需要进入到内存中的方法区的常量池(进入常量池规则:如果常量池中没有这个常量,就创建一个,如果有就不再创建了)。常量相同的字符串,地址一样,所以如果相同的字符串地址一样。String类重写了equals方法,比较的是属性值,s1和s2的属性值都是“abc”,所以是true

String s = new String(“abc”);s首先会在常量池创建“abc”字符串常量,当new的时候就会在堆内存中创建一个对象,此时会把常量池中的字符串常量拷贝一份副本到给到堆内存中的对象,堆内存中的这个对象就会把地址值赋给s。常量池中对象的地址值和堆内存中对象的地址值是不一样的,s指向的是堆内存中的对象,不是常量池中的对象。此时堆内存中有一个对象,常量池中有一个对象,所以创建了2个对象。

二、CopyOnWrite

并发下线程安全的(因为修改方法加了 ReentrantLock 锁),

底层修改(remove、add等)原理:修改时,数组拷贝原生方法(System.arraycopy)拷贝一个容器,再往新的容器里修改这个新的数据,最后把新的容器的引用地址赋值给了之前那个旧的的容器地址(注:但是在添加这个数据的期间,其他线程如果要去读取数据,仍然是读取到旧的容器里的数据)

  1. 适合“读多写少”的操作(场景)。
  2. 需要在遍历期间防止线程间的冲突。如果是其它类型的集合(ArrayList、HashMap),在遍历的时候,修改,就会报错(fail-fast快速失败机制)。

注:fail-fast机制:put和remove(Object)方法中都对modCount进行了加1操作,forEach遍历的时候,如果modCount和expectedModCount不等,则抛出异常。

2.1 CopyOnWriteArrayList

CopyOnWriteArrayList

CopyOnWriteArraySet 是一个集合,所以它不能有重复集合。因此,CopyOnWriteArrayList 额外提供了 addIfAbsent()addAllAbsent() 这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!

CopyOnWrite 的机制虽然是线程安全的,但是在add操作的时候不停的拷贝是一件很费时的操作,所以使用到这个集合的时候尽量不要出现频繁的添加操作,而且在迭代的时候数据也是不及时的,数据量少还好说,数据太多的时候,实时性可能就差距很大了。在多读取,少添加的时候,他的效果还是不错的(数据量大无所谓,只要你不添加,他都是好用的)

注:由于修改拷贝的缘故,容器如果很大的话,和容易触发垃圾回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伍特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值