每天一学(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 错误使用,强制放入同步代码块。

相关推荐
ktkiko114 天前
线性池学习
jvm·线程·线程池·进程
轩情吖22 天前
C++11(下)
开发语言·c++·线程池·条件变量·visual studio·bind·包装器
王·小白攻城狮·不是那么帅的哥·天文1 个月前
Spring框架使用xml方式配置ThreadPoolTaskExecutor线程池,并且自定义线程工厂
xml·java·spring·线程池
Winston Wood1 个月前
Java线程池详解
java·线程池·多线程·性能
雪碧聊技术1 个月前
多线程4:线程池、并发、并行、综合案例-抢红包游戏
java·线程池·多线程·并发·并行·复用线程
阿维的博客日记2 个月前
jvm学习笔记-轻量级锁内存模型
jvm·cas·轻量级锁
阑梦清川2 个月前
JavaEE初阶---多线程(五)---定时器/线程池介绍
java·java-ee·线程池·定时器
七禾页话2 个月前
自定义线程池
java·线程池
HKJ_numb12 个月前
多线程——线程池
java·设计模式·线程池·多线程·简单工厂模式·拒绝策略
hong_zc2 个月前
Java 多线程(五)—— 阻塞队列、wait、notify
java·阻塞队列