• 一起Talk Android吧(第三百六十八回:多线程之精准唤醒)


    各位看官们,大家好,上一回中咱们说的是Android中多线程之线程间通信的例子,这一回中咱们介绍的例子是多线程之精准唤醒。闲话休提,言归正转。让我们一起Talk Android吧!

    看官们,我们在上一章回中通过唤醒/等待机制实现了线程之间的通信,本章回中再介绍另外一种技术来实现线程之间的通信:Condition。

    概要介绍

    它是JUC包中的内容,它也是使用唤醒/等待机制实现线程之间的通信,不过它自带了await()和signal()/signalAll()方法来实现等待和唤醒操作。在程序中可以使用不同的Condition对象来完成唤醒/等待操作,大家想想看这样就可以通过不同的对象来控制不同的唤醒/等待操作,因此我们称其为精准唤醒。而普通对象的唤醒/等待操作只能使用相同对象去完成,因此我们称其为普通唤醒。

    示例程序

    接下来我们通过具体的程序来演示如何实现精准唤醒。

    public class ThreadLock {
        public static void main(String[] args) {
           // 使用Lock锁和Condition对线程进行精准唤醒,以实现线程间的通信
            class ProducerAndCustomer {
                //临界资源或者叫共享资源
                private int criticalResource;
                //定义锁
                private Lock threadLock;
                //定义condition
                private Condition conditionP;
                private Condition conditionC;
    
                public ProducerAndCustomer() {
                    criticalResource = 0;
                    threadLock = new ReentrantLock();
                    conditionP = threadLock.newCondition();
                    conditionC = threadLock.newCondition();
                }
    
                public void produce() {
                    //操作共享资源前加锁
                    threadLock.lock();
                    //如果有共享资源,生产者停止生产,进行睡眠状态,等待消费者唤醒
                    while (criticalResource > 0) {
                        try {
                            System.out.println("produce criticalResource = "+criticalResource+" sleeping");
                            conditionP.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    criticalResource += 1;
                    System.out.println("produce finished CriticalResource : "+criticalResource);
                    //生产者生产了共享资源,唤醒消费者去消费
                    conditionC.signal();
                    //操作共享资源后去锁
                    threadLock.unlock();
                }
                public void consume() {
                    //操作共享资源前加锁
                    threadLock.lock();
                    //如果没有共享资源,消费者停止生产,进行睡眠状态,等待生产者唤醒
                    while (criticalResource <= 0) {
                        try {
                            System.out.println("consume CriticalResource = "+criticalResource+" sleeping");
                            conditionC.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //消息者消费完共享资源,唤醒生产者生产资源
                    criticalResource -= 1;
                    System.out.println("consume finished CriticalResource : "+criticalResource);
                    conditionP.signal();
                    //操作共享资源后去锁
                    threadLock.unlock();
                }
            }
    
           ProducerAndCustomer obj = new ProducerAndCustomer();
    
            new Thread(()->{
                for (int i=0; i<3; i++) {
                    obj.produce();
                }},"Produce: ").start();
    
            new Thread(()->{
                for (int i=0; i<3; i++) {
                    obj.consume();
                }},"Consume: ").start();
        }
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    上面的程序和上一章回的程序类似,还是生产者与消费者的问题,不同的地方是使用了LOCK锁来同步线程,其实使用同步方法同步线程也可以,大家可以自己动手去实践。最大的不同在于使用了Condition对象的唤醒、等待操作机制来实现线程之间的通信。我们在程序中关键地方添加了注释,方便大家理解程序。

    编译并且运行上面的程序可以得到以下结果:

    produce finished CriticalResource : 1
    produce criticalResource = 1 sleeping
    consume finished CriticalResource : 0
    consume CriticalResource = 0 sleeping
    produce finished CriticalResource : 1
    produce criticalResource = 1 sleeping
    consume finished CriticalResource : 0
    consume CriticalResource = 0 sleeping
    produce finished CriticalResource : 1
    consume finished CriticalResource : 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    从上面的运行结果中可以看到生产者和消费者交替运行,不再像线程同步程序中的运行结果一样生产者和消费者单独运行。这和上一章回中程序运行的结果相同。这说明使用精准唤醒操作和使用普通唤醒操作都可以实现线程之间的通信。

    看官们,关于Android中多线程之精准唤醒的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

  • 相关阅读:
    ES6 - 模块化
    电脑硬盘里的文件能保存多久?电脑硬盘文件突然没了怎么办
    MyBatis choose、when和otherwise标签简介说明
    【UDS基础】简单介绍“统一诊断服务“
    leetcode做题笔记172. 阶乘后的零
    常见的系统类别汇总——包含OA/CRM/ERP/SCM
    计算机网络的相关知识点总结
    注解的使用
    TensorFlow入门(十八、激活函数)
    蓝桥杯嵌入式cubeMX自动生成的gpio.c文件解析
  • 原文地址:https://blog.csdn.net/talk_8/article/details/126084153