ImageVerifierCode 换一换
格式:PPTX , 页数:100 ,大小:395.63KB ,
文档编号:3592653      下载积分:28 文币
快捷下载
登录下载
邮箱/手机:
温馨提示:
系统将以此处填写的邮箱或者手机号生成账号和密码,方便再次下载。 如填写123,账号和密码都是123。
支付方式: 支付宝    微信支付   
验证码:   换一换

优惠套餐
 

温馨提示:若手机下载失败,请复制以下地址【https://www.163wenku.com/d-3592653.html】到电脑浏览器->登陆(账号密码均为手机号或邮箱;不要扫码登陆)->重新下载(不再收费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录  
下载须知

1: 试题类文档的标题没说有答案,则无答案;主观题也可能无答案。PPT的音视频可能无法播放。 请谨慎下单,一旦售出,概不退换。
2: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
3: 本文为用户(三亚风情)主动上传,所有收益归该用户。163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

1,本文(Java第11章-多线程课件.pptx)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!

Java第11章-多线程课件.pptx

1、第11章 多线程学习目标学习目标:理解多线程的概念,并能应用Thread子类和实现Runnable接口的对象来构建Thread对象;掌握Thread类构造方法及线程名称,熟悉线程优先级及Thread相关字段,理解线程的生命周期和相关状态,并能运用线程的其他方法;掌握线程同步与互斥的概念,能够运用同步关键字synchronized来声明同步的方法,熟悉生产者与消费者模型的定义并能进行设计。第第11章章 多多线程线程n11.1 程序程序、进程与、进程与线程线程n11.2 多线程多线程n11.3 线程线程类类ThreadThreadn11.4 实实训:龟兔赛跑训:龟兔赛跑n11.5 习题习题11.1

2、程序、进程与线程程序、进程与线程1.进程进程与线程区别与与线程区别与联系联系2进程和程序区别及联系进程和程序区别及联系 程序是存放在磁盘上的一系列代码和数据的执行映像,是一个静止的实体;进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位,是一个执行中的程序,它是动态的实体;线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。1.1.进程与线程区别与联系进程与线程区别与联系 1)划分尺度:线程更小,所以多线程程序并发性更高。2)资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源。3)地址空间:进

3、程拥有独立的地址空间,同一进程内多个线程共享其资源。4)处理器调度:线程是处理器调度的基本单位。5)执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程。2 2进程和程序区别及联系进程和程序区别及联系(1)进程和程序区别 1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。2)进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程。而这一点正

4、是程序无法做到的,由于程序没有和数据产生直接的联系,既使是执行不同的数据的程序,他们指令的集合依然是一样的,所以无法唯一地标识出这些运行于不同数据集上的程序。3)进程还具有并发性和交往性,这也与程序的封闭性不同。(2)进程和程序联系 1)进程是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在一定的数据集上运行的全部动态过程。2)一个进程肯定有一个与之对应的程序,而且只有一个。而一个程序有可能没有与之对应的进程(因为它没有执行),也有可能有多个进程与之对应(运行在几个不同的数据集上)。3)进程和线程都是由操作

5、系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。如图11-1所示。图11-1 进程、线程和应用程序之间的关系 简而言之,一个程序至少有一个进程,一个进程至少有一个线程,线程的划分尺度小于进程,使得多线程程序的并发性高。11.2多线程多线程11.2.1构建构建Thread子类对象子类对象11.2.2用实现

6、用实现Runnable接口的对象构建接口的对象构建Thread对象对象11.2.3 案例案例1:通过实现:通过实现Runnable接口创建线接口创建线 先从多任务谈起。多任务就是能同时运行两个或两个以上的程序,而且这些程序似乎在同时运行。比如,一边上网浏览网页一边看视频。这时计算机同时完成了两个任务。注意,计算机只有一个CPU,实际上是不能同时完成两个或两个以上程序的。计算机在完成一项任务时,CPU还有很多时间是空闲着的。操作系统正是将CPU的空闲部分分配给其他程序,从而给人的印象是在同时完成几项任务。多线程通过把多任务的原理用到程序的更低一层中,进一步发展了这一原理。在多线程程序中,单个程序

7、似乎能同时执行多个任务。每个任务通常被称为一个线程(thread),能同时运行一个以上线程的程序为多线程程序。11.2.1构建构建Thread子类子类对象对象 线程模型在Java中,由java.lang.Thread类进行定义和描述。程序中的线程都是Thread的实例,因此用户可以通过创建Thread的实例或定义来创建Thread子类的实例和控制自己的线程。继承Thread类创建一个新的线程语法如下:完成线程真正功能的代码放在类的run()方法中,当一个类继承Thread类后,就可以在该类中覆盖run()方法,将实现该线程的代码写入run()方法中,然后同时调用Thread类中的start()

8、方法执行线程,也就是调用run()方法。Thread对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作的功能代码被写在run()方法中。这个run()方法必须使用如下语法格式:当执行一个线程程序时,就自动产生一个线程,主方法正是在这个线程上运行的。当不再启动其他线程时,该程序就为单线程程序,主方法线程启动由Java虚拟机负责,程序员负责启动自己的线程。语法如下:【例11-1】从Thread类派生线程举例。解题思路:在下面的代码中,类printingThread扩展了Thread类。代码:程序threads.javathreads.javaimport java.applet.App

9、let;import java.awt.*;import java.awt.event.*;public class threads extends Applet implements ActionListener Button button1,button2;printingThread Thread1;public void init()button1=new Button(Start thread);button1.addActionListener(this);button2=new Button(stop thread);button2.addActionListener(this)

10、;add(button2);add(button1);Thread1=new printingThread();public void actionPerformed(ActionEvent e)if(e.getSource()=button1)Thread1.start();if(e.getSource()=button2)Thread1.animateFlag=false;class printingThread extends Thread boolean animateFlag=true;public void run()int i=0;while(animateFlag)System

11、.out.println(hello from Java+i);i+;运行结果如图11-2所示。图11-2 Thread类派生线程运行结果【说明】程序运行结果是在DOS屏幕下不停地打印“Hello from Java i”,i在不断地增加,直到线程停止。11.2.2用实现用实现Runnable接口的对象构建接口的对象构建Thread对象对象 处理多线程的第二种方法是实现Runnable接口。实现Runnable接口的语法如下:实现Runnable接口的类的对象创建线程以后,该线程的启动将使得对象的run()方法被调用。通过这种方式创建线程的过程是:把Runnable的一个实例作为参数传递给Th

12、read类的一个构造方法,该实例对象提供线程体run()。使用Runnable接口启动新的线程的步骤如下:1)建立Runnable对象2)使用参数为Runnable对象的构造方法创建Thread实例。3)调用start()方法启动线程。通过Runnable接口创建线程时程序员首先需要编写一个实现Runnable接口的类,然后实例化该类的对象,这样就建立了Runnable对象;接下来使用相应的构造方法创建Thread实例;最后使用该实例调用Thread类中的Start()方法启动线程。11.2.3 案例案例1:通过实现:通过实现Runnable接口创建接口创建线线解题思路:Welcome类实现了

13、Runable接口。在Thread1类的main()方法中,以Welcome类的两个实例对象分别创建了t1,t2两个线程,并将线程启动。在创建的线程中,Welcome类的run()方法就是线程体,其中“int i”是线程的数据。当t1,t2启动时,是从Welcome类对象的run()开始执行,每个线程分别打印输出两个字符串。代码:程序代码:程序Thread.javaThread.javaimport java.lang.*;public class Thread public static void main(String args)Thread t1=new Thread(new Welco

14、me();Thread t2=new Thread(new Welcome();t1.start();t2.start();class Welcome implements Runnableint i;public void run()while(true)System.out.println(欢迎您!+i+);if(i=2)break;运行结果为:11.3 线程类线程类Thread11.3.1Thread类构造方法及线程名称类构造方法及线程名称11.3.2线程优先级与线程优先级与Thread相关字段相关字段11.3.3线程生命周期与线程状态线程生命周期与线程状态11.3.4线程其他方法线程其

15、他方法11.3.5线程同步与互斥线程同步与互斥11.3.6同步关键字同步关键字synchronized11.3.7生产者与消费者模型生产者与消费者模型11.3.8案例案例2:模拟多个生产者和消费者操作公共资源:模拟多个生产者和消费者操作公共资源 从上面的介绍中可以了解到,在Java中处理多线程的方法有两种:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。11.3.1Thread类构造方法及线程类构造方法及线程名称名称1.Thread类

16、构造类构造方法方法2.线程名称线程名称1.Thread类构造方法Thread类是java.lang包中的一个类,从这个类中实例化的对象代表线程,程序中启动一个新线程需要建立Thread实例。Thread类的构造方法被重载了八次,构造方法如下:(1)Runnable target 实现了Runnable接口的类的实例。要注意的是Thread类也实现了Runnable接口,因此,从Thread类继承的类的实例也可以作为target传入这个构造方法。(2)String name线程的名子。这个名子可以在建立Thread实例后通过Thread类的setName方法设置。如果不设置线程的名子,线程就使用

17、默认的线程名:Thread-N,N是线程建立的顺序,是一个不重复的正整数。(3)ThreadGroup group 当前建立的线程所属的线程组。如果不指定线程组,所有的线程都被加到一个默认的线程组中。关于线程组的细节将在后面的章节详细讨论。(4)long stackSize 线程栈的大小,这个值一般是CPU页面的整数倍。如x86的页面大小是4KB.在x86平台下,默认的线程栈大小是12KB。一个普通的Java类只要从Thread类继承,就可以成为一个线程类。并可通过Thread类的start方法来执行线程代码。虽然Thread类的子类可以直接实例化,但在子类中必须要覆盖Thread类的run方

18、法才能真正运行线程的代码。【例11-2】使用Thread类建立线程举例。解题思路:下面的代码建立了两个线程:thread1和thread2.Thread1类的run方法,使用this.getName()输出了当前线程的名字,由于在建立线程时并未指定线程名,因此,所输出的线程名是系统的默认值,也就是Thread-n的形式。在main()程序中,首先输出主线程的线程名,然后在调用start方法时,系统自动调用run方法运行。代码:程序Thread1.javapublic class Thread1 extends Thread public void run()System.out.println

19、(this.getName();public static void main(String args)System.out.println(Thread.currentThread().getName();Thread1 thread1=new Thread1();Thread1 thread2=new Thread1();thread1.start();thread2.start();运行结果为:【说明】任何一个Java程序都必须有一个主线程。一般这个主线程的名子为main.只有在程序中建立另外的线程,才能算是真正的多线程程序。也就是说,多线程程序必须拥有一个以上的线程。2.线程名称 Th

20、read类有一个重载构造方法可以设置线程名。除了使用构造方法在建立线程时设置线程名,还可以使用Thread类的setName方法修改线程名。要想通过Thread类的构造方法来设置线程名,必须在Thread的子类中使用Thread类的public Thread(String name)构造方法,因此,必须在Thread的子类中也添加一个用于传入线程名的构造方法。下面的代码给出了一个设置线程名的例子。【例11-3】设置线程名称举例解题思路:在main方法中建立了三个线程:thread1、thread2和thread3.其中thread1通过构造方法来设置线程名,thread2通过setName方法

21、来修改线程名,thread3未设置线程名。代码:程序Thread2.javapublic class Thread2 extends Thread private String who;public void run()System.out.println(who+:+this.getName();public Thread2(String who)super();this.who=who;public Thread2(String who,String name)super(name);this.who=who;public static void main(String args)Thre

22、ad2 thread1=new Thread2(thread1,MyThread1);Thread2 thread2=new Thread2(thread2);Thread2 thread3=new Thread2(thread3);thread2.setName(MyThread2);thread1.start();thread2.start();thread3.start();运行结果为:【说明】在类中有两个构造方法:(1)public sample2_2(String who)这个构造方法有一个参数:who这个参数用来标识当前建立的线程。在这个构造方法中仍然调用Thread的默认构造方法

23、public Thread()。(2)public sample2_2(String who,String name)这个构造方法中的who和第一个构造方法的who的含义一样,而name参数就是线程名。在这个构造方法中调用了Thread类的public Thread(String name)构造方法,也就是下面的代码super(name)。注意:在调用start方法前后都可以使用setName设置线程名,但在调用start方法后使用setName修改线程名,会产生不确定性,也就是说可能在run方法执行完后才会执行setName;Thread类的start方法不能多次调用,如不能调用两次thre

24、ad1.start()方法。否则会抛出一个IllegalThreadStateException异常。11.3.2线程优先级与线程优先级与Thread相关相关字段字段 每个线程都具有各自的优先级,线程的优先级可以在程序中表明该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的几率比较小,比如垃圾回收线程的优先级就较低。在默认情况下,一个线程继承其父线程的优先级。Thread类有3个有关线程优先级的静态常量:MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORI TY。其中MIN_

25、PRIORITY代表最小优先级,通常为1。MAX_PRIORITY代表最高优先级,通常为10。NORM _PRIORITY代表普通优先级,缺省数值为5。对应一个新建线程,系统会遵循如下的原则为其指定优先级:新建线程将继承创建它的父线程的优先级。父线程是指执行创建新线程对象语句的线程,它可能是程序的主线程,也可能是某一个用户自定义的线程。一般情况下,主线程具有普通优先级。另外,用户可以通过调用Thread类的setPriority(int a)方法来修改系统自动设定的线程优先级,使之符合程序的特定需要。a取值是:Thread.MIN_PRIORITY,Thread.MAX _PRIORITY,T

26、hread.NORM _PRIORITY。【例11-4】设置线程优先级举例 解题思路:几个新的线程是在main()方法中产生,首先创建线程threadA,它的优先级为8,其次创建形成threadB,它启动之前的优先级为2。为显示继承优先级创建threadC和 threadD,它们启动前优先级分别为7,在运threadC时,执行run方法中的r,创建threadD时,调用threadC的r,它继承threadC的优先级,开始线程main,先休眠3秒,然后在已运行的threadA中调用setPriority(),使优先级改成3。代码:程序代码:程序SetPriority.javapublic cl

27、ass SetPriority extends Object private static Runnable makeRunnable()Runnable r=new Runnable()public void run()for(int i=0;i5;i+)Thread t=Thread.currentThread();System.out.println(in run()-优先级=+t.getPriority()+,线程名=+t.getName();tryThread.sleep(2000);catch(InterruptedException x)return r;public stati

28、c void main(String args)Thread threadA=new Thread(makeRunnable(),threadA);threadA.setPriority(8);threadA.start();Thread threadB=new Thread(makeRunnable(),threadB);threadB.setPriority(2);threadB.start();Runnable r=new Runnable()public void run()Thread threadC=new Thread(makeRunnable(),threadC);thread

29、C.start();Thread threadD=new Thread(r,threadD);threadD.setPriority(7);threadD.start();tryThread.sleep(3000);catch(InterruptedException x)threadA.setPriority(3);System.out.println(in main()-threadA.getPriority()=+threadA.getPriority();运行结果如下:11.3.3线程生命周期与线程线程生命周期与线程状态状态 线程创建后,启动run就开始了它的生命周期,直至run方法返

30、回时,该线程终止。没有任何方法可以强制某个线程终止运行,但可以用interrupt请求终止某个线程的运行。线程也不能连续不断地运行,否则其他线程就没有机会执行。因此,线程在不同的生命阶段有不同的状态。线程的状态与生命周期如图11-3所示。图11-3 线程状态转化图 如上图所示:当用new 创建完一个线程对象后,该线程处于新建状态;当线程对象调用了start()后,该线程处于就绪状态;如果处于就绪状态的线程获得CPU时间片,开始执行run方法的线程执行体,该线程处于运行状态;如果线程调用了sleep()或者调用了一个阻塞式I/O方法等,该线程处于阻塞状态;如果线程的run()执行完成或者抛出一个

31、未捕获的异常等原因,该线程处于死亡状态。新建的线程在它的一个完整的生命周期中通常要经历如下的5种状态:1)新建:当一个Thread类及其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它已经有了相应的内存空间和 其他资源。2)就绪:处于新建状态的线程被启动后,将进入线程队列排队等待CPU服务,此时它已经具备了运行的条件,一旦轮到它来享用CPU资源时,就可以脱离创建它的主线程独立开始自己的生命周期了。3)运行:当就绪状态的线程被调度并获得处理器资源时,便进入运行状态。每一个Thread类及其子类的对象都有一个重要的run()方法,当线程对象被调度执行时,它将自动调用本对象的run()方

32、法,从第一句开始顺序执行。run()方法定义了这个 线程的操作和功能。4)阻塞:一个正在执行的线程如果在某些特殊情况下,如被人为挂起或需要执行费时的输入输出操作时,将让出CPU并暂时中止自己的执行,进入阻塞状态。阻塞时它不能进入排队队列,只有当引起阻塞的原因被消除时,线程才可以转入就绪状态,重新进入到线程队列中排队等待CPU资源,以便从原来终止处开始继续运行。5)死亡:处于死亡状态的线程不具有继续运行的能力。线程死亡的原因有二,一个是正常运行的线程完成了它的全部工作,即执行完 了run()方法的最后一个语句并退出,另一个是线程被提前强制性地终止。11.3.4线程其他线程其他方法方法Thread

33、类提供sleep(),join(),yield(),interrupt(),isAlive(),stop(),currentThread()等方法,来控制和协调线程。1.sleep()有时优先级高的线程需要优先级低的线程做一些工作来配合它,此时为让优先级高的线程让出CPU资源,使得优先级低的线程有机会运行,可以使用sleep(int millsecond)方法。线程在休眠时被打断,JVM就抛出InterruptedException异常。因此,必须在try-catch语句块中调用sleep方法。2.join()t.join()方法使当前的线程等待,直到t结束为止,线程恢复到runnable状态

34、。join()有三种格式:1)join()调用t.join()时,当前线程将等待线程t结束后再继续执行。2)join(long millis)调用t.join()时,当前线程将等待线程t结束或最多等待millis(ms)后,再继续执行。3)join(long millis,int nanos)调用t.join()时,当前线程将等待线程t结束或最多等待millis(ms)+nanos(ns)后,再继续执行。3.yield()优先级同级时,调用该方法后,可以使具有与当前线程相同优先级的线程有运行的机会。如果有多个相同优先级并且是Runnable状态,该方法将把调用yield()方法的线程放入可运行

35、线程去排队,并允许对首线程运行。也就是交出CPU一段时间,暂停当前正在执行的线程对象,并执行其他线程。4.interrupt()当线程调用sleep()方法处于休眠状态,一个占有CPU资源的线程可以让休眠的线程调用interrupt()方法吵醒自己,即导致线程发生IllegalThreadStateException异常,从而结束休眠,重新排队等待CPU资源。5.isAlive()当线程调用start()方法并占有CPU资源后该线程的run()方法开始运行,在run()方法没有结束之前调用isAlive()返回true,当线程处于新建态或死亡态时调用isAlive()返回false。注意:一个

36、已经运行的线程在没有进入死亡态时,不要再给它分配实体,由于线程只能引用最后分配的实体,先前的实体就成为了垃圾,并且不能被垃圾回收机制收集。6.stop()当线程完成运行并结束后,将不能在运行。除线程正常运行结束外,还可用其他方法控制其停止,即用stop()方法强行 终止线程。但不提倡采用这种方法,因为它容易造成线程的不一致。可以与interrupt()联合使用。7.currentThread()Thread类的静态方法,可以用类名调用,返回当前正在使用CPU资源的线程。8.suspend()与rusume()11.3.5线程同步与线程同步与互斥互斥 在多线程程序中,线程是共享内存,也就是共享资

37、源,因此,有时会出现共享数据不一致的危险。如银行的账目,同时有多个用户访问同一个账号,有借有贷,若程序对线程没有管理好,就可能破坏账目数据。Java语言为控制访问共享资源,提供了高层同步的概念。线程之间通过对资源的竞争,包括共享的数据和硬件资源,所产生的相互制约关系,这类线程间的主要问题是互斥和死锁问题,这类关系被称为互斥关系。典型的例子是“售票厅售票应用”。售票厅剩余100张票,10个窗口去卖这些票。这10个窗口,就是10条线程,售票厅就是他们共同操作的资源,其中剩余的100张票就是这个资源的一个状态。线程买票的过程就是去递减这个剩余数量的过程,需要对统一资源进行控制访问。Java提供了关键

38、字synchronized来进行互斥操作的控制。11.3.611.3.6同步关键字同步关键字synchronizedsynchronized 同步线程就是让多个线程协调地工作。线程的同步保护了共享的数据,使线程的控制和切换能同步执行。Java的多线程机制提供了关键词synchronized来声明同步方法。一个类中的任何方法都可声明为synchronized。当某对象用synchronized修饰时,表明该对象在同一时刻只能由一个线程访问。当一个线程进入声明为synchronized的方法后,就能保证在任何其他线程访问这个方法之前完成自己各条命令的执行。换言之,如果某一线程试图访问一个已经启动的

39、synchronized方法,则这个线程必须等待,直到启动的线程执行完毕。锁定一个对象和一段代码声明格式为:锁定一个方法声明格式为:【例11-5】一个最简单的同步实例解题思路:该例运行结果显示“1 0”或“0 1”,则表明实现同步,如果没有同步,显示“1 1”。代码:程序SyncExample.javaublic class SyncExample private static Object lockObject=new Object();private static class Thread1 extends Threadint x,y;public void run()synchroniz

40、ed(synchronized(lockObjectlockObject)x=0;x=0;y=0;y=0;System.out.printlnSystem.out.println(x);(x);private static class Thread2 extends Threadprivate static class Thread2 extends Thread intint x,yx,y;public void run()public void run()synchronized(synchronized(lockObjectlockObject)x=1;x=1;y=1;y=1;Syste

41、m.out.printlnSystem.out.println(y);(y);public static void main(String public static void main(String argsargs)new Thread1().run();new Thread1().run();new Thread2().run new Thread2().run();();运行结果如下:11.3.7生产者与消费者生产者与消费者模型模型 生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其

42、中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。【例11-6】定义公共资源类解题思路:代码中的变量number是保存的公共数据。并且定义两个方法increace()和decreace()分别增加number的值和减少number的值。由于多线程的原因,必须加上synchronized

43、关键字,注意while判断的条件。代码:程序PublicResource.java public class public class PublicResourcePublicResource /公共资源类 private int number=0;public synchronized void increace()/增加公共资源 while(number!=0)Try wait();catch(InterruptedException e)e.printStackTrace();number+;System.out.println(number);notify();public synch

44、ronized void decreace()/减少公共资源 while(number=0)try wait();catch(InterruptedException e)e.printStackTrace();number-;System.out.println(number);notify();【例11-7】定义生产者线程和消费者线程解题思路:程序ProducerThread.java和ConsumerThread.java定义了生产者线程和消费者线程,并模拟多次生产和消费,即增加和减少公共资源的number值。代码:程序ProducerThread.javaProducerThread.

45、javapublic class ProducerThread implements Runnable/生产者线程,负责生产公共资源 private PublicResource resource;public ProducerThread(PublicResource resource)this.resource=resource;public void run()for(int i=0;i 10;i+)try Thread.sleep(long)(Math.random()*1000);catch(InterruptedException e)e.printStackTrace();res

46、ource.increace();代码:程序ConsumerThread.java public class ConsumerThread implements Runnable /消费者线程,负责消费公共资源 private PublicResource resource;public ConsumerThread(PublicResource resource)this.resource=resource;public void run()for(int i=0;i 10;i+)try Thread.sleep(long)(Math.random()*1000);catch(Interru

47、ptedException e)e.printStackTrace();resource.decreace();/*生产者线程,负责生产公共资源*/public class ProducerThread implements Runnable private PublicResource resource;public ProducerThread(PublicResource resource)this.resource=resource;Overridepublic void run()for(int i=0;i 10;i+)try Thread.sleep(long)(Math.rand

48、om()*1000);catch(InterruptedException e)e.printStackTrace();resource.increace();/*消费者线程,负责消费公共资源*/public class ConsumerThread implements Runnable private PublicResource resource;public ConsumerThread(PublicResource resource)this.resource=resource;Overridepublic void run()for(int i=0;i 10;i+)try Thre

49、ad.sleep(long)(Math.random()*1000);catch(InterruptedException e)e.printStackTrace();resource.decreace();11.3.8案例案例2:模拟多个生产者和消费者操作:模拟多个生产者和消费者操作公共公共资源资源解题思路:模拟多个生产者和消费者操作公共资源的情形,结果须保证是在允许范围内。代码:ProducerConsumerTest.javapublic class public class ProducerConsumerTestProducerConsumerTest public static v

50、oid main(String public static void main(String argsargs)PublicResourcePublicResource resource=new resource=new PublicResourcePublicResource();();new Thread(new new Thread(new ProducerThreadProducerThread(resource).start();(resource).start();new Thread(new new Thread(new ConsumerThreadConsumerThread(

侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|