每天一学(2)

目录

1、线程池是如何知道线程任务是否完成

2、阻塞队列的有界和无界

3、ConcurrentHashMap底层实现原理

5、CAS机制

[6、wait 和 notify 为什么要放在 synchronized](#6、wait 和 notify 为什么要放在 synchronized)


1、线程池是如何知道线程任务是否完成

线程池内部

当把任务丢给线程池去执行,调度工作线程, 通过同步调用执行 run () 方法,正常结束, 等待方法返回 直到结束,

线程外部:

线程池提供了isInterrupted () 方法 判断线程池的运行状态 结果是 意味着任务执行完成 submit 方法 通过 future.get() 方法 正常返回 意味着结束 没有返回则一直执行

引入CountDownLatch 计数器 进行倒计时 有两个方法 :

1、await()阻塞线程

2、countDown() 进行倒计时,一旦倒计时归零,所有阻塞在await()方法的线程都会被释放

2、阻塞队列的有界和无界

阻塞队列是特殊的队列,1、当队列为空,获取队列中元素的消费者线程,它会被阻塞,同时唤醒生产者线程,2、当队列中元素满了,向队列中添加元素的生产者线程,它会被阻塞,同时唤醒消费者线程。

有界队列: 阻塞队列中容纳的个数是有限的,比如去实例化一个ArrayBlocking List,可以在构造方法传一个整形的数字,表示基于数组的阻塞队列中,能够容纳的元素个数,称为

无界队列:就是没有设置固定大小的队列,并不是没有任何限制,而是元素存储量很大。无界队列存在比较大的潜在风险,并发量较大的情况下,线程池中几乎可以无限制的添加任务,容易导致内存溢出。

3、 ConcurrentHashMap底层实现原理

整体架构:

jdk1.8 由数组+红黑树+单向链表构成,默认初始化长度16的数组,由于核心仍是hashmap ,必然会存在hash冲突, 所有ConcurrentHashMap采用链式寻址的方式

解决hash 冲突:当hash冲突比较多的时候,会造成链表长度问题, jdk 1.8 引入红黑树,当数组长度大于64,并且链表长度大于8,单向链表会转化为红黑树。当链表长度小于8,红黑树就会退化为单项链表。

基本功能:

在hashmap基础上提供了并发安全的实现,通过对于node节点去加锁,来保证数据更新的安全性。性能方面优化:

jdk1.8、ConcurrentHashMap 的锁粒度是数组中某一个节点,

jdk1.7 、锁定的是segment 锁的范围要更大,性能上会更低,

引入红黑树,降低数据查询的时间复杂度

当数组长度不够的时候,对数组进行扩容, 引入了多线程并发扩容(多个线程对原始数组进行分片),每个线程负责对一个分片的迁移。

4、死锁发生的原因 怎么避免

死锁:多个锁去竞争同一个资源 造成相互等待,如果没有外部干预、将无法往下执行

导致死锁的条件:

  1. 互斥条件 共享资源x和y 只能被一个线程占用
  2. 请求和保持条件 A线程已经取得共享资源x 在等待共享资源y的时候,不释放x
  3. 其他线程不能强行抢占线程A 占有的资源
  4. 循环等待:线程A 等待B占有的资源 B等待A占有的资源

解决死锁:

通过人工干预来解决, 重启服务、或者kill 掉线程

破坏其中任意一种 (互斥条件没办法破话) 互斥条件是互斥锁的基本约束

5、CAS机制

CAS是java中unsafe类里面的一个方法,全称:Compare and Swap比较并交换

主要功能: 保证在多线程环境下,对于共享变量修改的一个原子性

例子: 有一个成员变量state默认值为0 ,定义了一个方法,逻辑为,先判断state是否为0,如果为0 就修改为1,在单线程没有任何问题,多线程下会存在原子性问题。 这是是一个 read -write 操作, 一般解决会在方法 加 synchronized同步锁来解决,但是加锁 会带来性能上的损耗, 所以可以采用CAS机制进行优化。

6、wait 和 notify 为什么要放在 synchronized

wait 和notify 为了实现多个线程之间的协调, 阻塞/被唤醒 。他俩必然成对出现,

要实现多线程之间的通信,除了管道流,只能通过共享变量的方法来实现,A线程修改共享变量s ,线程B 获得修改之后共享变量s的值

但是多线程本身具有并行执行的特征,同一时刻多个线程可以同步执行,线程B 在访问共享变量之前,必须要知道线程A已经修改过共享变量S, 修改完同时唤醒等待状态下的线程, synchronized 可以实现互斥条件,实现条件等待条件唤醒,为了避免wait /notify 错误使用,强制放入同步代码块。

相关推荐
王小义笔记4 天前
异步线程的@Async开发总结
java·开发语言·spring boot·线程池·异步
martian6656 天前
学懂C#编程:常用高级技术——学会C#多线程开发(三):学会线程池的使用
开发语言·c#·线程池·多线程
lpruoyu6 天前
【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【15】异步_线程池
线程池·completable·异步
专注VB编程开发20年7 天前
vb6多线程异步,VB.NET 全用API实现:CreateThread创建多线程,等待线程完成任务
爬虫·.net·线程池·vb6·vb6多线程·抢单·vba优化
北i13 天前
kakfa发版丢消息事件分析
后端·kafka·线程池
Micro麦可乐23 天前
Spring Boot整合Redis通过Zset数据类型+定时任务实现延迟队列
spring boot·redis·后端·线程池·延迟队列·zset数据类型
重整旗鼓~1 个月前
47.各种类型的线程池
java·线程池·并发
StartLFly1 个月前
数据结构与算法-10_阻塞队列
java·数据结构·队列·阻塞队列
ITfeib1 个月前
线程池在业务中的实践
线程池