目录

一、线程方法(三):wait-notify锁自定协调

1.实现规格

2.线程欠量

3.线程塞等

4.欠等互斥

二、线程安全(一).3:条件产生渡送执行

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锁自定协调

知识连接:

线程方法(一):中断和等待

线程方法(二):wait/notify等待通知机制

抢锁块里进行的 此线程等条件 厌锁欠执行另线程归条件 醒锁还执行锁协调模式

1.实现规格

锁往小里面加,锁协调 占最小的行 就可实现


2.线程欠量

每个线程 最多只能 在欠着一个执行同方线程同欠等条件方向的多个线程


3.线程塞等

线程 入阻塞地 等待条件,避免了 忙等待 浪费cpu的资源


4.欠等互斥

欠等条件互斥的线程 始终至少有另方 可条件地执行

但可能会因为 唤醒没通知到 它的对立条件可执行线程 而最终 一方条件不符 厌锁入眠 另方条件满足 但缺唤醒都在 待唤醒 阻塞


二、线程安全(一).3:条件产生渡送执行

知识连接:

线程安全(一).1:不安全原因和措施

线程安全(一).2:指令全排序

线程安全(一).4:写块串行保安全

线程安全(一).5:总

正确条件 从产生 能渡送到 执行处 的保障实现

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.execute里面渡前

渡前并发环境下 一次筛排可能的 才拿去送往 加锁开销大的官口检查

2.addWorker里面官口

官口加锁内 二次精确确定地 检查

  • 官路来源:

1.加锁

加锁造官路

2.原子指令

原子指令自带官路

  • 渡路上并发读取筛送:

1.加锁官需要

加锁造官路 有开销 需在渡路上 并发当时地 读取筛排 少送至些

2.原子指令官不需要

CAS原子指令的官路 无开销 渡路上的全部送至 都无所谓的


三、阻塞队列的解耦通信

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效率

只在队列满空时 才会使另方阻塞随机调度下 双方少遇阻塞地 可以连续地执行,执行效率

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐