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

Posted talk_8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起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();
    

上面的程序和上一章回的程序类似,还是生产者与消费者的问题,不同的地方是使用了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

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

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

以上是关于一起Talk Android吧(第三百六十八回:多线程之精准唤醒)的主要内容,如果未能解决你的问题,请参考以下文章

一起Talk Android吧(第三百八十八回:lifecycle)

一起Talk Android吧(第三百零八回:程序的主题)

一起Talk Android吧(第四百六十八回:实现自定义View中的布局功能)

一起Talk Android吧(第三百七十八回:给ViewPager添加indicator)

一起Talk Android吧(第三百三十八回: Android中的OkHttp一)

一起Talk Android吧(第三百四十八回:解析JSON数组三)