Java多线程编程:阻塞队列、wait-notify锁协调机制、线程安全[条件产生渡送执行]
目录
一、wait-notify锁协调机制
1.实现规格
2.线程欠量
3.线程塞等
4.欠等互斥
二、线程安全[条件 产生渡送执行]
1.临执行无缝能改路官口检查
2.加锁多铺一路上的无缝能改路
三、阻塞队列的解耦通信
1.直接交互
1.1锁同步
1.2锁协调-乒乓交替协调
1.2.1效率
2.间接交互
2.1组件更换直接交互对象
2.2组件分担功能实现 给封装共享使用
2.2.1实现所需的同步协调机制
2.2.2额外实现缓冲区管理
2.2.2.1锁协调-队列连续协调
2.2.2.1.1平衡速度
2.2.2.1.2效率
一、wait-notify锁协调机制
抢锁块里进行的 此线程等条件 厌锁欠执行、另线程归条件 醒锁还执行 的锁协调模式
1.实现规格
锁往小里面加,锁协调 占最小的行 就可实现
2.线程欠量
每个线程 最多只能 在欠着一个执行,同方线程 指 同欠等条件方向的多个线程
3.线程塞等
线程 入阻塞地 等待条件,避免了 忙等待 浪费cpu的资源
4.欠等互斥
欠等条件互斥的线程 始终至少有另方 可条件地执行
但可能会因为 唤醒没通知到 它的对立条件可执行线程 而最终 一方条件不符 厌锁入眠 另方条件满足 但缺唤醒 地都在 待唤醒 阻塞中
二、线程安全[条件 产生渡送执行]
正确条件 从产生 能渡送到 执行处 的保障实现
1.临执行无缝能改路官口检查
最后的 临执行 无 缝能改路 官口检查,检查正确条件来得被改、错误条件虚假唤醒来得
2.加锁多铺一路上的无缝能改路
唤醒的正确条件产生 到 最后执行的一路 都(加锁成)已无缝能改,唤醒后 到抢到锁后 再到在官口处 直接一定还是原来的正确条件 没改,也就不必 在官口处 去弄检查了
synchronized (this) {while (size == data.length) {// 2.往后就是最后的 无能修改条件穿插的 临执行 无缝能改路,在官口检查条件this.wait();// 1.正确条件产生并唤醒它后 经历锁竞争 一路上渡到官口时 条件可能已经改变}// 3.官口通过,执行条件:data[tail] = elem;tail++;if (tail == data.length) {tail = 0;}size++;this.notify();// notify期望唤醒 take中的wait
}
三、阻塞队列的解耦通信
1.直接交互
生产者消费者 直接交互地 在自己身上实现 锁同步与锁协调
// 直接交互
class DirectInteraction {private String sharedData;private boolean dataReady = false;private final Object lock = new Object();// 生产者public void produce(String data) {synchronized(lock) {while(dataReady) { // 必须知道消费者的状态,等待消费者取走数据try { lock.wait(); } catch (InterruptedException e) {}}sharedData = data;dataReady = true; // 必须设置消费者需要的状态lock.notify(); // 必须直接通知消费者}}// 消费者public String consume() {synchronized(lock) {while(!dataReady) { // 必须知道生产者的状态,等待生产者提供数据try { lock.wait(); } catch (InterruptedException e) {}}String result = sharedData;dataReady = false; // 必须设置生产者需要的状态lock.notify(); // 必须直接通知生产者return result;}}
}
1.1锁同步
在生产者消费者身上 加锁同步,生产消费 都是 整步地串行,处理了线程安全问题
1.2锁协调-乒乓交替协调
无缓冲区 是在生产者消费者身上 锁块里 设置检查 是否标记地 只能双方 乒乓交替执行 地锁协调
1.2.1效率
始终在阻塞一方,随机调度下 阻塞成了 必须双方交替地执行,执行效率低
2.间接交互
生产者与消费者之间 引入中间组件-队列 解耦通信
// 间接交互
class IndirectInteraction {private BlockingQueue<String> queue = new ArrayBlockingQueue<>(10); // 已经在队列组件里 实现好了 生产消费的 锁同步与锁协调// 生产者public void produce(String data) {try {queue.put(data); // 生产者 只与共享的队列交互 调用队列里面的put方法即可,不关心消费者了} catch (InterruptedException e) {}}// 消费者public String consume() {try {return queue.take(); // 消费者 只与共享的队列交互 调用队列里面的take方法即可,不关心生产者了} catch (InterruptedException e) { return null; }}
}
2.1组件更换直接交互对象
内容互渗透、执行互拖欠 的紧密协调关系 转移,生产者与消费者 改成 与队列直接交互,彼此 间接交互 独立无联了
2.2组件分担功能实现 给封装共享使用
2.2.1实现所需的同步协调机制
封装在队列里实现的 put、take方法 已加锁同步 与用锁协调,生产者消费者 直接共享地 使用实现
2.2.2额外实现缓冲区管理
队列 能缓冲 生产消费不同伐协调 的待置数据,允许了 生产消费 以不同的速度运行
2.2.2.1锁协调-队列连续协调
有缓冲区后 是在队列组件上 锁块里 填取检查 队列是否满空地 可以一方连续执行 地锁协调
2.2.2.1.1平衡速度
在队列满空下 阻塞限制一方连续执行、另方可连续执行地 实况平衡 双方速度
2.2.2.1.2效率
只在队列满空时 才会使另方阻塞,随机调度下 双方少遇阻塞地 可以连续地执行,执行效率高