20220801笔记

今天学了下面这几样

collection接口Map接口集合实现线程安全线程的原子性、可见性、有序性新建线程的方式线程池的种类以及特点线程池的拒绝‍策略

collection接口

collection接口的主要有两个子接口,分别为List和Set。

  • List接口

    List接口是有序对象集合,主要有三个实现类,分别为ArrayList、LinkedList、Vector。

  • ArrayList底层由数组实现,查找元素复杂度为O(1),增删元素涉及到数组扩容和拷贝元素,时间复杂度为O(n)。每次扩容1.5倍。

  • LinkedList底层由链表实现,查找元素复杂度为O(n),增删元素时间复杂度为O(1)。

  • Vector与ArrayList几乎一样,不过因为考虑了线程安全,所以会稍慢一点。

  • Set接口

    Set接口是无序不重复对象集合,不过它的实现类TreeSet实现了SortedSet接口,通过Comparator或Comparable维护排序顺序实现了有序Set。主要实现类有HashSet、LinkedHashSet、TreeSet。

  • HashSet由HashMap实现,允许有Null元素出现,查找时间复杂度为 O(1) ,默认加载因子为0.75,最大容量为16。

  • LinkedHashSet由LinkedHashMap实现,允许有Null元素出现,查找时间复杂度为 O(1) ,因为除了使用哈希表存储数据,还使用了一条双向链表,所以在需要遍历的场景中速度会更快一点。默认加载因子为0.75,最大容量为16。

  • TreeSet由TreeMap实现,不允许有Null出现,其内部元素有序,可按照自然排序也可根据使用的比较器排序,操作时间复杂度为 O(log n)。

Map接口

Map为键值对对象集合,其中每一个对象都有两个属性,分别为key和value,可能会有多个相同的value,但是相同的key只能同时存在一个。其主要实现类主要有HashMap、LinedHashMap、HashTable和TreeMap。

HashMap

  • 底层实现:jdk1.7以前是由数组加链表实现,jdk1.8及以后是通过数组加链表/红黑树实现,当链表长度大于8的时候链表转化为红黑树,小于6的时候转为链表。

  • 为何使用数组:因为查找速度快,并且HashMap中扩容机制是2倍,ArrayList中是1.5倍。

  • 是否允许为空:key和value都允许为空。

  • 扩容机制:每次扩容2倍。

LinedHashMap

在HashMap的基础上添加了一条双向链表维护顺序,保证了在迭代的时候元素的有序性。

HashTable

与HashMap区别不大,不过保证了线程安全,效率稍低。同时key与value不允许为空。底层数组长度可以为任意数值,默认为11。(不推荐使用)

TreeMap

TreeMap由红黑树实现,同时实现了SortedMap接口,保证了元素的有序性。key和value允许为空,

集合实现线程安全

  1. 使用synchronize或Lock加锁以此保证线程安全。(速度慢)

  2. 使用ConcurrentHashMap实现线程安全,速度也快。底层主要通过CAS和volatile还有synchronize实现,初始化状态由volatile+CAS解决。

线程的原子性、可见性、有序性

  • 原子性:同一时间只能由一个线程对当前数据进行操作。

  • 可见性:当前数据被线程修改时,其他线程应当可以及时观察到。

  • 有序性:如果两个线程不能通过happens-before原则观察顺序,那么虚拟机可以对其进行任意重排序,则应当遵循happens-before原则。

新建线程的方式

  1. 通过继承Thread类创建.

  2. 实现Runnable接口创建线程。

  3. 通过线程池创建线程。

  4. 通过Callable和Future可以创建有返回值的线程。

线程池的种类以及特点

  1. Single Thread Executor线程池:线程池中只有一个线程,当一个线程结束会新创建一个线程继续执行。适用于多任务线性执行的情况。

  2. Cached Thread Pool线程池:可缓存的线程池,当线程池的任务小于规模时,会自动回收对于线程,当线程池的任务多于规模的时候,会自动创建新的线程。极端情况下会 创建过多的线程,耗尽 CPU 和内存资源 ,适用于大批量,处理速度快的任务。

  3. Fixed Thread Pool线程池:固定线程数的线程池,空闲时线程会一直等待。适用于需要长期执行的任务。

  4. Schedule Thread Pool线程池:固定长度的线程池,以延迟或定时的方式执行任务。适用于周期性执行的任务。

线程池的拒绝策略

  1. CallerRunPolicy:当有新的任务提交以后,如果线程池没有能力只执行,那就让提交任务的线程去执行。

  2. AbortPolicy:直接抛出RejectedExecutionException异常,可以让开发直接获取到拒绝状态,能够根据业务去重试或者丢弃任务。

  3. DiscardPolicy:直接丢弃任务,此方式有一定风险,因为无法感知到任务到底是被执行还是丢弃。

  4. DiscardOldestPolity:丢弃当前队列中最老的任务,与上一种不同之处在于丢弃的是存活时间最长的任务,同样,他也有丢失数据的风险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值