天天看点

多线程程序设计学习(6)Producer-Consumer模式

Producer-Consumer【生产消费者模式】

一:Producer-Consumer pattern的参与者

--->产品(蛋糕)

--->通道(传递蛋糕的桌子)

--->生产者线程(制造蛋糕的线程)

--->消费者线程(吃掉蛋糕的线程)

二:Producer-Consumer pattern模式什么时候使用

--->大量生产+大量消费的模式

三:Producer-Consumer pattern思考

--->【生产消费者模式】,肩负保护数据安全性使命的是通道参与者。通道参与者参与进行线程间的共享互斥,让生产着能正确将数据传递到消费者手中。

--->通道(桌子)的put和take方法都使用了【独木桥模式】,而生产者和消费者都不想依赖table类的详细实现,也就说,生产者不必理会其他线程,只管生产并put,同样消费者也不必理会其他线程,只管take就好。而线程的共享互斥,synchronized,wati,notifyAll这些考虑的多线程操作的代码,全都隐藏在通道table类里。提高了table的复用性。

--->生产者消费者模式,存在两方处理速率不同的话,必然造成一方等待,或占用通道大量内存的问题。

--->多线程合作的口决

        线程的合作要想:放在中间的东西

        线程的互斥要想:应该保护的东西

--->多生产者对单一消费者,如果情况合理,一方可以不用考虑互斥,就不用加锁,提升性能。

四进阶说明

--->习惯编写java多线程。当所调用的方法抛出,或内部抓住异常:InterruptedException.

        ==>通常传递给我们两个信息。(1)这是‘需要花点时间’的方法(2)这是‘可以取消’的方法

        ==>告诉我们方法内部有这三个选手:java.lang.Object类里的wait方法        

                                                                                     java.lang.Thread类里的sleep方法

                                                                                     java.lang.Thread类里的join方法

--->需要花点时间的方法

        wait==>执行wait方法的线程,进入wait set里休眠,等待notify,notifyAll唤醒。在休眠期间不会活动,因此需要花费时间。

        sleep==>执行sleep,会暂停执行参数内所设置的时间,这也是需要花费时间

        join==>会等待制定的线程结束为止。才执行本线程。也就是花费直到制定线程结束之前的这段时间

--->可以取消的方法。

        因为需要花费时间,会降低程序的响应性,所以我们会希望像下面这样可以在中途放弃(取消)执行这个方法

        1取消wait方法等待notify,notifyAll唤醒的操作

        2取消sleep方法等待设置长度时间的操作

        3取消join方法等待其他线程结束的操作

--->取消线程等待的详细解说

       (1) A线程的实例为athread,线程体内部执行Thread.sleep(1000)时,想取消其睡眠状态。则需要B线程中取消。

                --->在B线程中用athread.interrupt().

                --->则A线程终止睡眠,并抛出或被抓住InterruptedException

                --->这个时候A线程的catch块的代码,至关重要。

      (2) A线程的实例为athread,线程体内部执行wait()时,想取消等待notify,notifyAll唤醒的操作。则需要B线程中取消。

                --->在B线程体中用athread.interrupt().

                --->则A线程终止等待状态,并尝试重新获取锁定。

                --->获取锁定后,抛出或被抓住InterruptedException

      (3)A线程的实例为athread,线程体内部执行join(),想等待其他线程执行结束。则需要B线程中取消。

                 --->在B线程中用athread.interrupt().

--->线程对象.interrupt(),Thead.interrupted,线程对象.isinterrupted()区别

        ==>interrupt()让等待或休眠的线程变成中断状态,抛出异常

        ==>interrupted()检查线程的中断状态

                                        是中断状态,返回true,并将中断状态修改成非中断状态

                                        不是中断状态,返回false,不做任何操作

        ==>isinterrupted简单的检查线程是否为中断状态,是返回true,不是返回false,不做任何操作

     Producer-Consumer案例

        三个生产蛋糕的线程,三个消费蛋糕的线程,一个传递蛋糕的桌子。

传递蛋糕的桌子

多线程程序设计学习(6)Producer-Consumer模式
多线程程序设计学习(6)Producer-Consumer模式

View Code

生产蛋糕的线程

多线程程序设计学习(6)Producer-Consumer模式
多线程程序设计学习(6)Producer-Consumer模式

吃掉蛋糕的线程

多线程程序设计学习(6)Producer-Consumer模式
多线程程序设计学习(6)Producer-Consumer模式

测试类

多线程程序设计学习(6)Producer-Consumer模式
多线程程序设计学习(6)Producer-Consumer模式

测试结果:

[尚晓飞师傅]put尚晓飞师傅的蛋糕0

[范林军师傅]put范林军师傅的蛋糕0

【顾客1】get尚晓飞师傅的蛋糕0

【顾客2】get范林军师傅的蛋糕0

[黄栓林师傅]put黄栓林师傅的蛋糕0

【顾客3】get黄栓林师傅的蛋糕0

[尚晓飞师傅]put尚晓飞师傅的蛋糕1

【顾客3】get尚晓飞师傅的蛋糕1

[范林军师傅]put范林军师傅的蛋糕1

【顾客1】get范林军师傅的蛋糕1

[黄栓林师傅]put黄栓林师傅的蛋糕1

【顾客2】get黄栓林师傅的蛋糕1

[尚晓飞师傅]put尚晓飞师傅的蛋糕2

上一篇: C#之装饰者