condition精准控制

Lock版的生产者消费者问题

那么在synchronized中呢,我们是使用wait和notify来控制线程的。

复制代码
public synchronized void increment() throws InterruptedException {
       while (number != 0) {
            // 等待
            this.wait();

        }
        Thread.sleep(100);
        number++; // 业务
        System.out.println(Thread.currentThread().getName() + " => " + number);
        // 通知其它线程我+1加完了
        this.notifyAll();

    }
复制代码

 

用了Lock之后、会有一些细微的改变,wait->condition.await, notify->condition.signal

复制代码
class doSomething {

    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    // +1
    public void increse() throws InterruptedException {
        lock.lock();
        try {

            while (number != 0) {
                condition.await();

            }
            Thread.sleep(100);
            number++;
            System.out.println(Thread.currentThread().getName() + "->" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            lock.unlock();
        }

    }


    // -1
    public void decrese() throws InterruptedException {

        lock.lock();
        try {
            while (number == 0) {
                condition.await();
            }
            Thread.sleep(100);
            number--;
            System.out.println(Thread.currentThread().getName() + "->" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

}
复制代码

思考:既然有了wait和notify、那为什么我们还要多此一举来使用condition的等待和唤醒呢?

  这是因为condition能够做到有序,精准的通知和唤醒线程

那么如何做到有序精准的来唤醒线程呢?

复制代码
public class C {
    public static void main(String[] args) {
        doSomething2 doSomething2 = new doSomething2();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                doSomething2.printA();

            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                doSomething2.printB();

            }

        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                doSomething2.printC();

            }

        }, "C").start();

    }
}

@SuppressWarnings("all")
class doSomething2 {

    private int number = 1;
    Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void printA() {
        lock.lock();
        try {
            while (number != 1) {
                // 等待
                condition1.await();
            }
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + "AAA");
            // 唤醒
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printB() {
        lock.lock();
        try {
            while (number != 1) {
                // 等待
                condition2.await();
            }
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + "BBB");
            // 唤醒
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printC() {
        lock.lock();
        try {
            while (number != 1) {
                // 等待
                condition3.await();
            }
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + "CCC");
            // 唤醒
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
复制代码

 

 

 

 

 

 

 

 

 

 


posted on   Love&Share  阅读(76)  评论(0编辑  收藏  举报

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示