项目9--利用多线程技术实现定时响铃_第1页
项目9--利用多线程技术实现定时响铃_第2页
项目9--利用多线程技术实现定时响铃_第3页
项目9--利用多线程技术实现定时响铃_第4页
项目9--利用多线程技术实现定时响铃_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、项目9 利用多线程技术实现定时响铃古凌岚 张婵 罗佳人民邮电出版社Java系统化项目开发教程知识要点线程的生命周期线程的创建 线程并发控制线程通信引子 为什么需要引入线程?日常生活中,我们人在同一时间可以做许多事,如在进餐的同时,还可以倾听朋友叙述的故事Java程序中为了模拟这种功能,引入了线程机制。简单点说,当一个程序能够同时完成多件事情时,就是所谓的多线程程序多线程应用较广泛9.1实战任务十一:实现闹钟启动的计时功能问题分析设定闹钟涉及两个时间点,一是闹钟时间,二是设置闹钟时的系统时间,当这两个时间点重叠时,铃声音乐将被播放,即闹钟响了闹钟设定后,需要不断地计算两个时间点间的差值,同时还要

2、求能够使用闹钟的其它功能,如上传铃声文件等多线程技术,可实现以上多个事务处理的互不影响,各自独立执行的效果9.1实战任务十一:实现闹钟启动的计时功能进程和线程程序是指具有完整功能的一段静态代码进程是指多任务操作系统中,每个程序的一次动态执行。其对应着代码加载、执行和直至执行完毕的一个完整过程处理器会为每次加载的进程分配一个独立的内存空间,若同一段代码被加载多次,则会被分配到不同的内存空间加以执行线程是CPU的最小执行单位,是进程内部的执行线索,但它与进程同样也有产生、发展和消亡三个阶段9.1实战任务十一:实现闹钟启动的计时功能进程和线程的关系9.1实战任务十一:实现闹钟启动的计时功能多线程示例

3、运行结果9.1实战任务十一:实现闹钟启动的计时功能上述程序执行的过程如下,可了解线程的整个生命周期(1)执行main方法,创建一个aloneThread类对象;(2)调用aloneThread类中aloneThread构造方法;(3)创建线程myThread对象,调用start方法,启动该线程;(4)执行线程体run方法;(5)执行FOR循环;(6)在屏幕上打印出数字0-5,每打印出一个数字,调用sleep方法,让线程进入休眠状态(暂停)1000毫秒;(7)在循环过程中,若中断程序,则显示出错误信息;(8)循环执行完成,程序结束。9.1实战任务十一:实现闹钟启动的计时功能线程五个状态9.1实战

4、任务十一:实现闹钟启动的计时功能创建线程方法一是创建Thread类的子类方法二是利用Runnable接口方法三是利用Callable接口9.1实战任务十一:实现闹钟启动的计时功能Thread类通过创建该类的子类,来创建线程Thread类的常用方法9.1实战任务十一:实现闹钟启动的计时功能方法一示例9.1实战任务十一:实现闹钟启动的计时功能利用Runnable接口Runnable接口只有一方法public void run()应用示例如右侧代码9.1实战任务十一:实现闹钟启动的计时功能线程并发控制一个进程中的多个线程要共用当前进程的资源,如内存空间、变量、I/O设备等如何有序高效地利用资源,是多

5、线程应用的关键问题9.1实战任务十一:实现闹钟启动的计时功能相关术语并行:多个CPU实例或者多台机器同时执行一段处理逻辑,是真正的同时并发:通过CPU调度算法,让用户感觉是同时执行,但实际并非真的同时线程安全:指在并发情况下,某段代码经过多线程调用,线程的调用顺序不会影响这段代码的执行结果互斥:当多个线程需要访问同一资源时,要求在一个时间段内只能允许一个线程来操作共享资源(临界区)。这里线程之间不需要知道对方的存在,执行顺序是乱序同步:线程间需要通过交替执行,访问公共资源,来共同完成一个任务线程安全:指要控制多个线程对某个资源的有序访问或修改9.1实战任务十一:实现闹钟启动的计时功能互斥性、可

6、见性和顺序性Java引入了synchronized 关键字,实现了互斥性、可见性和顺序性,以保证多个线程有序访问进程资源9.1实战任务十一:实现闹钟启动的计时功能未使用互斥锁的存取款示例9.1实战任务十一:实现闹钟启动的计时功能9.1实战任务十一:实现闹钟启动的计时功能从运行结果可知,有时存取款的顺序有误(如第二组结果)9.1实战任务十一:实现闹钟启动的计时功能在方法上加了互斥锁的存取款示例9.1实战任务十一:实现闹钟启动的计时功能9.1实战任务十一:实现闹钟启动的计时功能从这次运行结果可知,存取款线程是有序进行的9.1实战任务十一:实现闹钟启动的计时功能利用synchronized实现互斥性

7、的原理Java中的每个对象都包含了一把锁,它自动成为对象的一部分(不必为此写任何特殊的代码)调用该对象的任何synchronized方法时,对象就会被锁定,该对象的其他synchronized方法此时也都不可被调用,除非第一个方法完成了自己的工作,并解除锁定9.1实战任务十一:实现闹钟启动的计时功能利用synchronized实现线程同步使用synchronized修饰方法,该方法称为同步方法synchronized修饰成员方法时,则一个线程要执行该方法,必须取得该方法所在的对象的锁,即某个synchronized成员方法被调用时,其它synchronized成员方法不可被调用;synchro

8、nized修饰类方法时,则一个线程要执行该方法,必须获得该方法所在的类的类锁,即某个synchronized类方法被调用时,其它synchronized类方法同时也被锁住synchronized修饰一个代码块,则可使得当不同块所需的锁不冲突时,则不必对整个对象加锁。采用对代码块加锁,可以减小锁的粒度9.1实战任务十一:实现闹钟启动的计时功能代码块同步的形式为synchronized(obj) /obj表示对象,为共享资源 /code9.1实战任务十一:实现闹钟启动的计时功能在代码块上加互斥锁的使用示例9.1实战任务十一:实现闹钟启动的计时功能从运行结果可知,两个线程的执行是有序的9.1实战任务

9、十一:实现闹钟启动的计时功能异步多线程的同步执行有时主线程和子线程是异步启动的,但又需要以同步方式执行实现方法join方法isAlive方法示例先来看一个程序代码9.1实战任务十一:实现闹钟启动的计时功能上述代码执行时,无法显示出a+的最后结果,为什么?join方法使用join方法,修改上述代码中黑色字体部分,可以解决问题9.1实战任务十一:实现闹钟启动的计时功能alive方法alive应用示例运行结果9.1实战任务十一:实现闹钟启动的计时功能9.1实战任务十一:实现闹钟启动的计时功能死锁现象两个或多个线程分别拥有不同的资源,而同时又需要对方释放资源才能继续运行如果锁使用不当,就会出现死锁现象

10、9.1实战任务十一:实现闹钟启动的计时功能死锁的产生需同时满足四个条件(以过独木桥为例)互斥条件:一个资源每次只能被一个进程使用。独木桥每次只能通过一个人。请求与保持条件:一个进程因请求资源而阻塞时,并对已获得的资源保持不放。乙不退出桥面,甲也不退出桥面。不剥夺条件: 进程已获得的资源,在未使用完之前,不能强行剥夺。甲不能强制乙退出桥面,乙也不能强制甲退出桥面。循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。如果乙不退出桥面,甲不能通过,甲不退出桥面,乙不能通过。9.1实战任务十一:实现闹钟启动的计时功能避免死锁现象的解决方法需要加多个锁时,按照顺序来加;设置锁的超时时限;创建线

11、程和锁的关系图,通过对其进行检测,防止死锁。9.1实战任务十一:实现闹钟启动的计时功能线程优先级Java支持为每个线程设置优先级优先级高的线程在排队执行时,会有更多机会获得CPU资源去运行Thread类规定了三个优先级MAX_PRIORITY最高优先级NORM_PRIORITY普通优先级,也是默认优先级MIN_PRIORITY最低优先级9.1实战任务十一:实现闹钟启动的计时功能Thread类的setPriority方法可用于设置线程的优先级public final void setPriority(int newPriority)/setPriority方法声明setPriority方法应用示

12、例9.1实战任务十一:实现闹钟启动的计时功能 运行结果9.1实战任务十一:实现闹钟启动的计时功能需要说明的是虽然设置了线程优先级,仍会无法确保该线程一定先执行,它有很大的随机性。因为线程的执行,是抢占资源后才能执行的操作,最多是给于线程优先级较高的多一点抢占资源的机会而已,能不能抢到却是不一定的9.1实战任务十一:实现闹钟启动的计时功能线程通信机制实际应用中,需要多个任务彼此间可以协作,一起解决某个问题,例如:制作木桌,其工序及顺序为:购买木材、制作桌子各部件、上油漆和组装,需按照顺序完成所有工序才算是完工为了实现线程间协作(线程通信),需要解决两个问题线程间共享资源的互斥是线程执行状态的传递

13、9.1实战任务十一:实现闹钟启动的计时功能对于线程间共享资源的互斥的另一个途径Java可以让当前线程挂起,直到某些外部条件发生变化,表示可以让当前线程继续具体的方法是,通过Object的wait、notify和notifyAll方法来实现的,这些均为final方法)9.1实战任务十一:实现闹钟启动的计时功能wait方法作用是告诉当前线程放弃对当前对象监视器的控制权并睡眠,直到另一个线程调用notify方法public final void wait() throws InterruptedException/方法声明notify方法作用是唤醒正在等候当前对象监听器的单个线程。若有多个线程在等待

14、,则任选其中一个。但只有拥有对象监视器的线程才能使用该方法public final void notify()/方法声明9.1实战任务十一:实现闹钟启动的计时功能线程通信的实现先看一个例子:苹果丰收了,果农会将苹果摘下来,分等级出售。摘苹果的时候,果农甲将树上的苹果摘下放入筐中,树下的果农乙会从这个筐中取苹果,依质量好坏分类放入其他筐中。甲不停摘下苹果放入筐中,乙不停地从筐中取出苹果。如果筐中苹果已取完,则乙必须等待直到甲又摘了苹果放入筐中;如果筐已满,而乙还未拿走一个的话,甲也必须等待直到乙开始取苹果9.1实战任务十一:实现闹钟启动的计时功能两个线程间的协作(通信)类似于摘苹果,两个线程间的

15、协作(通信),产生数据(苹果)的线程被称为生产者,而使用数据的线程为消费者以摘苹果为例,实现生产者和消费者的示例,完整代码参见 教材9.1实战任务十一:实现闹钟启动的计时功能任务实施利用多线程机制,实现闹钟工具软件中,定时判断是否到达定时时间的功能创建内部类TimeListen线程,用于监听,即每隔1秒获取一次剩余时间,且一旦到闹铃时间,则播放铃声(在下一任务中实现)在启动闹钟设置时,启动TimeListen线程完整代码参见教材9.1实战任务十一:实现闹钟启动的计时功能同步练习实现闹钟工具软件中当前时间的动态显示。同步练习音乐播放器项目MusicPlayerProj中,实现音乐播放进度条的动态

16、显示。9.2实战任务十二:实现铃声播放功能问题分析闹钟工具软件还有几个任务需要同时执行需要实时地显示当前系统时间一旦到达设置的闹钟时间,还需要播放所选定的铃声音乐。铃声播放线程,与实战任务十一中的闹钟定时判断是否到达设定时间线程,有逻辑关系,但此间闹钟工具中其它功能应可以使用,因此,也需要定义为线程9.2实战任务十二:实现铃声播放功能音乐播放Java提供了音乐播放API,支持wav格式文件javax.sound.sampled包提供了AudioInputStream、AudioFormat、AudioSystem、DataLine和SourceDataLine,用于实现音乐文件的读取、格式定义

17、,以及输出到混频器等操作9.2实战任务十二:实现铃声播放功能未使用线程音乐播放示例9.2实战任务十二:实现铃声播放功能9.2实战任务十二:实现铃声播放功能9.2实战任务十二:实现铃声播放功能音乐播放的流程(1)调用AudioSystem类的getAudioInputStream静态方法,创建音频输入流类AudioInputStream的对象audioInputstream;(2)调用audioInputstream对象的getFormat方法,创建音频格式对象format;(3)实例化嵌套类DataL,根据指定格式format,构造信息对象;(4)调用AudioSystem类的

18、getLine静态方法,获得信息对象的源数据行SourceDataLine类对象dataline;(5)调用dataline对象的start方法,启动流的读写操作;(6)调用audioInputstream对象的read方法,从音乐文件中读取内容到字节数组bufbytes中,如果读取值为-1,则表示文件读取完毕;(7)调用dataline对象的write方法,每次将字节数组bufbytes中的readbytes个字节写入到混频器中,即播放音乐。9.2实战任务十二:实现铃声播放功能同步练习音乐播放器项目MusicPlayerProj中,能够选择音乐,并播放音乐9.2实战任务十二:实现铃声播放功能利用线程实现动画动画实现的基本原理Java的图形界面,每个组件都是由paint/paintComponent方法绘制出来的,通过定时重新绘制组件,就可以产生动画效果,定时触发绘制是由线程来实现的,绘制动作本身则是通过重写paint/paintComponent方法完成。9.2实战任务十二:实现铃声播放功能时钟动画的实现实现效果源码参见教材9.2实战任务十二:实现铃声播放功能时钟实现的关键依据三角函数来计算时、分、秒针的位置,如指针的x、y坐标,分别来自于sin和cos公式,角度的计算则是根据圆的弧度与

温馨提示

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

评论

0/150

提交评论