多线程补充案例

上传人:无*** 文档编号:127784652 上传时间:2022-07-30 格式:DOC 页数:25 大小:265KB
收藏 版权申诉 举报 下载
多线程补充案例_第1页
第1页 / 共25页
多线程补充案例_第2页
第2页 / 共25页
多线程补充案例_第3页
第3页 / 共25页
资源描述:

《多线程补充案例》由会员分享,可在线阅读,更多相关《多线程补充案例(25页珍藏版)》请在装配图网上搜索。

1、第五章 补充案例案例5-1 继承Thread类创立多线程一、案例描述 1、 考核知识点编 号:00105002名 称:继承Thread类创立多线程2、 练习目的 掌握如何通过继承Thread类实现多线程的创立。 掌握Thread类中run()措施和start()措施的使用。3、 需求分析在程序开发中,会遇到一种功能需要多种线程同步执行才干完毕的状况。这时,可以通过继承线程类Thread,并重写Thread类中的run()措施来实现。为了让初学者熟悉如何创立多线程,在案例中将通过继承Thread类方式创立线程,并实现多线程分别打印099的数字的功能。4、 设计思路(实现原理)1) 自定义一种类D

2、emo,使其继承Thread类。2) 在Demo类中重写run()措施,在run()措施内编写一种for循环,循环体内打印:“Demo:”+目前循环次数。3) 编写测试类Example01,在Example01类的main()措施中,创立一种Demo对象,并执行其 start()措施,接着编写一种for循环,循环体内打印:“main:”+目前循环次数。二、案例实现class Demo extends Thread public void run() for (int x = 0; x 100; x+) System.out.println(Demo:+x); public class Exam

3、ple01public static void main(String args) Demo d = new Demo();d.start();for(int x=0; x100; x+)System.out.println(main:+x); 运营成果如图5-1所示。图5-1 运营成果三、案例总结1、通过继承Thread类,并重写Thread类中的run()措施可以实现多线程。2、Thread类中,提供的start()措施用于启动新线程,线程启动后,系统会自动调用run()措施。3、main()措施中有一条主线程在运营。案例5-2 实现Runnable接口创立多线程一、案例描述 1、 考核知

4、识点编 号:00105003名 称:实现Runnable接口创立多线程2、 练习目的 掌握如何通过实现Runnable接口方式创立多线程。 掌握如何使用Thread类的有参构造措施创立Thread对象。3、 需求分析在Java中只支持单继承,因此通过继承Thread类创立线程有一定的局限性,这时可以使用另一种方式,即实现Runnable接口来创立线程。通过这种方式需要在Thread(Runnable target)的构造措施中,传递一种实现了Runnable接口的实例对象。接下来在案例中将通过实现Runnable接口方式创立线程,并实现多线程分别打印099的数字的功能。4、 设计思路(实现原理

5、)1) 自定义一种类Demo,使其实现Runnable接口。2) 在Demo类中覆写run()措施,在措施编写一种for循环,循环体内打印:目前线程名称:+目前循环次数。3) 编写测试类Example02,在Example02类的main()措施中,创立一种Demo对象,运用Thread(Runnable target)构造措施创立2个线程对象,分别命名为“蜘蛛侠”和“钢铁侠”,并执行线程对象的start()措施,同步编写for循环,循环内打印“main:”+目前循环次数。二、案例实现class Demo implements Runnable public void run() for(in

6、t x=0; x100; x+)System.out.println(Thread.currentThread().getName()+:+x); public class Example02 public static void main(String args) Demo d = new Demo();Thread t1 = new Thread(d,蜘蛛侠);Thread t2 = new Thread(d,钢铁侠);t1.start();t2.start();for (int x = 0; x 100; x+) System.out.println(main: + x);运营成果如图5

7、-2所示。图5-2 运营成果三、案例总结1、可以把实现了Runnable接口并重写run()措施的实例对象,作为Thread有参构造措施的参数来创立多线程程序。2、使用Thread类的构造措施Thread(Runnabletarget, Stringname)创立线程对象时,还可以给线程指定新名称。3、思考一下:既然有了继承Thread类的方式,为什么还要有实现Runnable接口的方式?a) 可以避免由于Java的单继承带来的局限性。在开发中常常遇到这样一种状况,就是使用一种已经继承了某一种类的子类创立线程,由于一种类不能同步有两个父类,因此不能用继承Thread类的方式,那么就只能采用实现

8、Runnable接口的方式。b) 实现接口的方式,适合多种相似程序代码的线程去解决同一种资源的状况,把线程同程序代码、数据有效的分离,较好的体现了面向对象的设计思想。例如:一种售票程序继承了Thread类,在售票时启动了多种售票程序,但她们不是同一种对象,数据没有共享,这样就会浮现票数反复发售的状况;而当售票程序实现Runnable接口后,多种线程运营同一种售票程序,实现了票数共享的好处。案例5-3 设立后台线程一、案例描述 1、 考核知识点编 号:00105005名 称:后台线程2、 练习目的 理解后台线程的生命周期 掌握如何将线程设立为后台线程3、 需求分析默认状况下,新创立的线程都是前台

9、线程,若想使前台线程变为后台线程,可以使用setDaemon(true)措施实现,为了让初学者熟悉后台线程,案例中将通过设立一种后台线程并演示后台线程和程序结束之间的关系。4、 设计思路(实现原理)1) 自定义一种类Watcher,使其实现Runnable接口。2) 在Watcher类中覆写run()措施,在措施内编写一种for循环,循环体内打印:线程名称+循环次数。3) 编写测试类Example03,在Example03类的main()措施中,创立一种Watcher对象,运用Thread(Runnable target)构造措施创立线程对象并命名,将线程设立为后台线程,执行该线程的start

10、()措施,接着编写一种for循环,循环内打印循环次数。二、案例实现class Watcher implements Runnable public void run() for (int x = 0; x 0; i-) System.out.println(我是雅典娜女神,我立即死了!+i); if(i=1) System.out.println(我是雅典娜女神,我死了!);运营成果如图5-3所示。图5-3 运营成果三、案例总结1、在多线程程序中,一旦前台线程(例如主线程)结束,后台线程也就结束了。2、要将某个线程设立为后台线程,该线程的setDaemon()措施必须在start()措施之前调

11、用,否则会引起IllegalThreadStateException异常。案例5-4 线程的优先级一、案例描述 1、 考核知识点编 号:00105007名 称:线程的优先级2、 练习目的 理解线程中优先级的概念和作用 掌握设立线程优先级的措施 掌握线程设立优先级措施中的三个静态常量3、 需求分析在应用程序中,如果要对线程进行调度,最直接的方式就是设立线程的优先级。这时,可以通过线程的setPriority()措施来设立线程优先级别,实现对线程的调度功能。为了让初学者掌握线程的优先级,在案例中创立3个线程,分别为它们设立不同的优先级来演示不同优先级线程的调度。4、 设计思路(实现原理)1) 自定

12、义一种类Demo,使其实现Runnable接口。2) 在Demo类中重写run()措施,在措施内编写一种for循环,循环体内打印:线程名称+循环次数。3) 编写测试类Example04,在Example04类的main()措施中,创立一种Demo对象,运用Thread的构造措施创立三个线程对象并命名,使用setPriority()措施将其中两个线程的优先级设为最大和最小,最后启动三个线程的start()措施。二、案例实现class Demo implements Runnable public void run() for (int x = 0; x 0) try Thread.sleep(1

13、000); catch (InterruptedException e) e.printStackTrace();System.out.println(Thread.currentThread().getName() + 正在发售第 + (tickets-) + 张票);public class Example05 public static void main(String args) Ticket tr = new Ticket();Thread t1 = new Thread(tr);Thread t2 = new Thread(tr);Thread t3 = new Thread(tr

14、);t1.setName(窗口1);t2.setName(窗口2);t3.setName(窗口3);t1.start();t2.start();t3.start(); 运营成果如图5-5所示。图5-5 运营成果从运营成果可以看出,当程序启动后,“窗口1”、“窗口2”、“窗口3”线程共同发售tikcets,但是最后“窗口1”发售了第0张票、“窗口3”发售了第-1张票,从中可以推断当tickets=1时,某一种线程进入if分支语句后,线程休眠了1秒。在此期间,tickets的值仍然为1,其她两个线程也顺利进入了到if分支语句中,当线程休眠时间结束后,三个线程分别操作了ticket值,因此导致了ti

15、ckets值为负数。三、案例总结1、sleep(long millis)措施声明抛出InterruptedException异常,因此在调用该措施时应当捕获异常,或者声明抛出该异常。2、sleep()是静态措施,只能控制目前正在运营的线程休眠,而不能控制其他线程休眠。当休眠时间结束后,线程就会返回到就绪状态,而不是立即开始运营。案例5-6 线程让步一、案例描述 1、 考核知识点编 号:00105009名 称:线程让步2、 练习目的 理解线程让步的概念和作用 掌握设立线程让步的措施3、 需求分析在校园中,我们常常会看到同窗互相抢篮球,当某个同窗抢到篮球后就可以拍一会,之后她会把篮球让出来,人们重

16、新开始抢篮球,这个过程就相称于Java程序中的线程让步。在多线程程序中,可以通过线程的yield()措施将线程转换成就绪状态,让系统的调度器重新调度一次,达到线程让步的目的。案例中将在一种多线程程序中,通过yield()措施对其中一种线程设立线程让步来演示。4、 设计思路(实现原理)1) 自定义一种类Demo,使其实现Runnable接口。2) 在Demo类中覆写run()措施,在措施内编写一种for循环,循环体内,先执行线程让步的措施yield(),然后输出打印:线程名称+循环次数。3) 编写测试类Example06,在Example06类的main()措施中,创立一种Demo对象,运用Th

17、read的构造措施创立两个线程对象,并执行线程对象的start()措施,同步编写for循环,循环内打印“main:”+目前循环次数。二、案例实现class Demo implements Runnablepublic void run()for(int x = 0 ; x 5 ; x+)Thread.yield();System.out.println(Thread.currentThread().getName()+.+x);public class Example06 public static void main(String args)throws Exception Demo d =

18、 new Demo();Thread t0 = new Thread(d);Thread t1 = new Thread(d);t0.start();t1.start();for(int x = 0 ; x5 ; x+)System.out.println(main.+x);运营成果如图5-6所示。图5-6 运营成果三、案例总结1、在多线程程序中,可以通过设立线程让步,让系统的调度器重新调度一次CPU的分派。2、线程让步和线程休眠是不同样的,线程让步不会阻塞该线程,它只是将线程转换成就绪状态,而线程休眠,是让线程在一定期间内进入休眠等待状态,达到时间后线程再转换成就绪状态。案例5-7 线程插队

19、一、案例描述 1、 考核知识点编 号:00105010名 称:线程插队2、 练习目的 理解线程插队的概念和作用 掌握线程插队措施的使用3、 需求分析在火车站买票的时候,有的乘客着急赶火车,会插到队伍前面先买车票,其她乘客再买票。那么在多线程程序中,也可以通过线程插队,让插队的线程先执行完,然后本线程才开始执行。在案例中将通过使用join()措施来演示线程插队。4、 设计思路(实现原理)1) 自定义一种类Demo,使其实现Runnable接口。2) 在Demo类中覆写run()措施,在措施内编写一种for循环,循环体内打印:线程名称+循环次数。3) 编写测试类Example07,在Example

20、07类的main()措施中,创立一种Demo对象,运用Thread的构造措施创立两个线程对象,分别命名“排队队员”和“插队队员”,然后编写两个线程对象的start()措施,然后调用“插队队员”线程的join()措施。二、案例实现class Demo implements Runnable public void run() for (int x = 0; x 5; x+) System.out.println(Thread.currentThread().getName() + - + x); public class Example07 public static void main(Str

21、ing args) Demo jd = new Demo();Thread t1 = new Thread(jd);Thread t2 = new Thread(jd);t1.setName(排队队员);t2.setName(插队队员);t1.start();t2.start();try t2.join(); catch (InterruptedException e) e.printStackTrace();运营成果如图5-7所示。 图5-7 运营成果三、案例总结1、线程插队,可以让插队的线程先执行完,然后本线程才开始执行。2、使用线程插队join()措施时,需要抛出InterruptedE

22、xception异常。案例5-8 同步代码块的使用一、案例描述 1、 考核知识点编 号:00105012名 称:同步代码块2、 练习目的 掌握同步代码块作用 掌握同步代码块的使用措施 掌握同步代码块中锁对象的使用3、 需求分析生活中,会遇到两人上洗手间的问题,甲使用洗手间的时候会锁上门,乙看到门锁上了,就需要等甲使用完后再使用的。那么在多线程程序中,可以通过将共享资源放在同步代码块内来实现多种线程同步解决共享资源的问题。本案例将通过两个线程共享资源来演示同步代码块的使用。4、 设计思路(实现原理)1) 自定义一种类Demo,使其实现Runnable接口。2) 在Demo类中覆写run()措施,

23、在措施内编写synchronized同步代码块,在进入同步代码块时,打印线程名称,然后编写一种for循环,循环体内打印:运营线程名称+循环次数。当循环次数等于3时,跳出循环。3) 编写测试类Example08,在Example08类的main()措施中,创立一种Demo对象,运用Thread的构造措施创立两个线程对象,分别命名“张三”和“李四”,执行两个线程的start()措施。二、案例实现class Demo implements Runnable private Object obj = new Object();public void run() synchronized (obj) S

24、ystem.out.println(Thread.currentThread().getName()+ 进入洗手间,门以锁上);for (int i = 1; i 10; i+) System.out.println(Thread.currentThread().getName()+ 正在使用洗手间+i);if (i = 3) System.out.println(Thread.currentThread().getName()+ 用完,准备出去,锁打开);break;public class Example08 public static void main(String args) Dem

25、o d = new Demo();Thread t1 = new Thread(d, 张三);Thread t2 = new Thread(d, 李四);t1.start();t2.start();运营成果如图5-8所示。图5-8 运营成果三、案例总结1、同步代码块中的锁对象可以是任意类型的对象,但多种线程共享的锁对象必须是唯一的。2、锁对象的创立代码不能放到run()措施中,否则每个线程运营到run()措施都会创立一种新对象,这样每个线程都会有一种不同的锁,每个锁均有自己的标志位。线程之间便不能产生同步的效果。案例5-9 同步代码块嵌套导致死锁一、案例描述 1、 考核知识点编 号:00105

26、014名 称:死锁2、 练习目的 理解什么是死锁和导致死锁的因素3、 需求分析在编写多线程程序中,常常浮现多种同步代码块嵌套的状况,而此时如果没有控制好锁对象的一致性就会浮现死锁现象,接下来,在案例中通过同步代码块之间的互相嵌套来演示线程死锁。4、 设计思路(实现原理)1) 自定义一种类DieLock,使其继承Thread。2) 在DieLock类中创立两个静态常量objA、objB,分别是a锁、b锁。然后创立一种boolean类型的私有属性flag作为标示符,并编写DieLock的构造措施3) 重写run()措施,在措施内一方面判断flag的值。当flag值为true时,分别以objA和ob

27、jB 为锁对象,编写两个嵌套的同步代码块,并在同步代码块中打印flag值和锁对象名称;当flag为值为false时,编写flag为false时的代码,只是把锁对象的顺序更换一下。4) 编写测试类Example09,在Example09类的main()措施中,运用DieLock的构造措施,创立两个DieLock对象,传入的flag值分别为true和false,执行两个线程的start()措施。二、案例实现class DieLock extends Thread private boolean flag;static Object objA = new Object();static Object

28、 objB = new Object();public DieLock(boolean flag) this.flag = flag;public void run() if (flag) synchronized (objA) System.out.println(true - objA);synchronized (objB) System.out.println(true - objB); else synchronized (objB) System.out.println(false - objB);synchronized (objA) System.out.println(fal

29、se - objA); public class Example09 public static void main(String args) new DieLock(true).start();new DieLock(false).start();运营成果如图5-9所示。图5-9 运营成果三、案例总结当两个线程的同步代码块彼此拿着对方需要的锁时,程序不会停止,但会始终“卡顿”,这种现象就是“死锁”现象。案例5-10 多线程通信一、案例描述 1、 考核知识点编 号:00105015名 称:多线程通信2、 练习目的 掌握如何解决线程通信中的共享资源的安全问题3、 需求分析一条生产线的上下两个工序

30、,它们必须以规定的速率完毕各自的工作,才干保证产品在流水线中顺利的流转。在多线程的程序中,上下工序可以看作两个线程,这两个线程之间需要协同完毕工作,就需要线程之间进行通信。了让初学者掌握多线程通信,案例中将通过生产和消费鼠标这两个过程的多线程协调来演示。4、 设计思路(实现原理)1) 创立一种产品类Product,该类有三个属性分别是:产品名称name,产品数量count,和一种boolean类型的标示量flag。当flag值为false时,阐明产品未生产,当flag值为true时,阐明产品已生产。2) 在Product类中编写一种同步措施set(),每次调用set()措施时,表达要生成一种产

31、品。在set()措施中,编写一种while循环,当flag值为true时,调用该线程的wait()措施,让线程等待。在while循环体外,count值递增,并打印目前线程名称和产品名称及数量,最后将flag值设为true,并唤醒所有的线程。3) 在Product类中编写一种同步措施get(),每次调用get()措施时,表达要消费一件产品。在get()措施中,编写一种while循环,当flag值为false时,调用该线程的wait()措施,让线程等待。在循环体外,打印目前线程名称和被消费的产品名称和个数。最后将flag值设为false,并唤醒所有的线程。4) 编写一种生产类Producter,该

32、类定义了一种Product类型的成员变量和有参构造措施,构造措施中的参数用于为Product对象赋值,并且Producter类实现了Runnable接口。5) 重写Runnbale接口的run()措施,在run()措施内,执行死循环,每循环一次调用Product对象的set()措施。6) 编写一种消费类Customer,该类定义了一种Product类型的成员变量和有参构造措施,构造措施中的参数用于为Product对象赋值,并且Customer类实现了Runnable接口。7) 重写Runnable接口的run()措施,在run()措施内,执行死循环,每循环一次就调用producet对象的get

33、()措施。8) 编写一种测试类Example10,创立一种Product对象,生产者和消费者分别运用product对象创立各自的对象,最后使用Thread类创立2个“生产者”线程和2个“消费者”线程,并执行四个线程的start()措施。二、案例实现/定义产品类class Product private int count;/ 产品的计数器private String name;private boolean flag = false;/ set生产的措施public synchronized void set(String name) while (flag = true) try this.

34、wait(); catch (Exception e) this.name = name + count+;/ 鼠标0System.out.println(Thread.currentThread().getName() + 生产了第+ this.name + 个鼠标=);flag = true;this.notifyAll();/ get消费的措施public synchronized void get() while (flag = false) try this.wait(); catch (Exception e) System.out.println(Thread.currentTh

35、read().getName() + 消费了第+ this.name + 个鼠标);flag = false;this.notifyAll();/ 生产者类class Producter implements Runnable private Product p;Producter(Product p) this.p = p;public void run() while (true) p.set(鼠标);/ 消费者类class Customer implements Runnable private Product p;Customer(Product p) this.p = p;publi

36、c void run() while (true) p.get();public class Example10 public static void main(String args) Product p = new Product();Producter pr = new Producter(p);Customer cr = new Customer(p);Thread t1 = new Thread(pr);Thread t2 = new Thread(pr);Thread t3 = new Thread(cr);Thread t4 = new Thread(cr);t1.start();t2.start();t3.start();t4.start();运营成果如图5-10所示。图5-10 运营成果三、案例总结1、wait()、notify()和notifyAll()这三个措施的调用者都应当是同步锁对象,如果这三个措施的调用者不是同步锁对象,Java虚拟机就会抛出IllegalMonitorStateException异常。2、在线程通信中的,如果需要控制多种线程按照一定的顺序轮流执行,则这几种线程的锁对象必须是同一种锁对象。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!