Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章 多线程——Java中

上传人:E**** 文档编号:89369906 上传时间:2019-05-24 格式:PPT 页数:30 大小:240KB
返回 下载 相关 举报
Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章  多线程——Java中_第1页
第1页 / 共30页
Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章  多线程——Java中_第2页
第2页 / 共30页
Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章  多线程——Java中_第3页
第3页 / 共30页
Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章  多线程——Java中_第4页
第4页 / 共30页
Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章  多线程——Java中_第5页
第5页 / 共30页
点击查看更多>>
资源描述

《Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章 多线程——Java中》由会员分享,可在线阅读,更多相关《Java程序设计教程 教学课件 PPT 作者 张克军 陆迟 孙海伦 庞丽娜 第9章 多线程——Java中(30页珍藏版)》请在金锄头文库上搜索。

1、第9章 多线程Java中的并发协作,随着多核CPU的问世,使得多线程程序在开发中占有了更重要的位置,多线程编程技术已经成为开发人员必不可少的一项重要技能。Java是原生就支持多线程编程的开发语言,用其进行多线程开发既方便又高效,本章将介绍Java中多线程开发的相关知识,主要包括线程的基本使用、状态、调度、同步等方面。,9.1 线程的基本知识,本节将介绍关于多线程开发的一些基本知识,包括什么是线程,如何定义、创建、启动线程。只有掌握了这些基本知识,才能继续学习更高级、更复杂的多线程开发。,9.1.1 多线程编程的意义,多线程编程可以使程序具有两条或两条以上的并发执行线索,就像日常工作中由多人同时

2、合作完成一个任务。这在很多情况下可以改善程序的响应性能,提高资源的利用效率,在多核CPU年代,这显得尤为重要。然而滥用多线程也有可能给程序带来意想不到的错误,降低程序执行的效率。 例如,开发一个网上购物时自动邮件通知的程序,在单击提交按钮确认定单时,一方面要显示信息提示定单已确认,一方面应该自动给用户发送一份电子邮件。 如果是单线程模式,则需要等待邮件发送完成之后,再显示提示信息,由于邮件发送的过程相对较慢,可能要经过漫长的等待才看到确认信息,界面响应性能不是很好。 而显示定单确认信息与发送通知邮件这两个工作是没有相互约束关系的,完全可以一边显示提示信息,一边发送通知邮件,这样界面的响应性能会

3、提高很多,不用进行漫长的等待。,9.1.1 多线程编程的意义,9.1.2 定义自己的线程,Java中的线程有两方面的含义,一是一条独立的执行线索,二是java.lang.Thread类或其子类的对象。在Java中开发自己的线程有两种方式,包括继承Thread类与实现Runnable接口,这两种方式在不同的场合各有优缺点,本小节将对这两种方式进行详细的介绍。 1继承Thread类 2实现Runnable接口 3两种方式的比较,9.1.3 创建线程对象,上一小节介绍了如何编写描述线程任务的方法,本小节将介绍如何创建线程对象。对于继承Thread类与实现Runnable接口两种不同方式来说,在创建线

4、程对象这一步是有区别的,下边将分别介绍在这两种情况下如何创建线程对象。 1继承Thread类方式 2实现Runnable接口方式,9.1.4 启动线程,当线程对象创建完成后,其还只是一个普通的对象,并没有成为一条独立的执行线索。想让其成为独立的执行线索必须进行启动,在没有启动的情况下,开发人员可以像调用其他对象的方法一样调用线程对象中的任何可见方法。 下面的例子说明了这个问题,代码如下。 1 /创建Runnable实现类的对象 2 MyRunnable mr=new MyRunnable(); 3 /创建Thread对象 4 Thread t=new Thread(mr); 5 /调用Thre

5、ad对象中run方法 6 t.run();,9.1.4 启动线程,9.1.5 同时使用多个线程,上一小节最后提到,两条执行线索并发运行时,结果可能是不唯一的。这是因为,如果有多个没有同步约束关系的线程需要执行,调度线程将不能保证哪个线程先执行及其持续的时间,在不同的平台上,或在同一平台上多次运行可能会得到不同的结果。 Java中对于线程启动后唯一能够保障的就是:“每个线程都将启动,每个线程都会执行结束”。但谁会先执行谁会后执行,将没有保障,也就是说,就算一个线程在另一个线程之前启动,也无法保障该线程一定在另一个线程之前执行完毕。,9.1.5 同时使用多个线程,9.2 线程的状态,前面章节对线程

6、的基本编程进行了简单的介绍,本节将对线程的生命周期进行详细的讨论。线程对象自其被创建后,一般会经历生命周期中五种不同的状态。,9.3 线程的调度,前面已经介绍了,Java自动调度没有逻辑约束的线程时,其执行顺序是没有保障的。但是可以通过编程调用一些调度线程的方法,来实现一定程度上对线程的调度。但要注意的是,这些调度线程的方法,有些是有保障的,有些只是影响线程进入执行状态的几率。本节将介绍几个简单的线程调度的方法,下一节将会介绍比较复杂的线程的同步与调度。,9.3.1 睡眠,在线程执行的过程中,调用sleep方法可以让线程睡眠一段指定的时间,等指定时间到达后,该线程则会苏醒,并进入准备状态等待执

7、行。这是使正在执行的线程让出CPU的最简单方法之一,其方法签名如下。 public static void sleep(long millis)throws InterruptedException public static void sleep(long millis,int nanos)throws InterruptedException,9.3.2 线程的优先级,很多系统在对进程进行调度时,会采用优先级调度策略。Java中在对线程进行调度时,也采用了优先级调度策略,具体为:“优先级高的线程应该有更大的获取CPU资源而执行的概率,优先级低的线程并不是总不能执行”。也就是说,当前正在执行

8、的线程优先级一般不会比正在准备状态等待执行的线程优先级低。 Java中线程的优先级用110之间的整数表示,数值越大优先级越高,默认优先级为5。例如,在没有特别指定的情况下,主线程的优先级别为5。另外,对于子线程,其初始优先级与其父线程的优先级相同。也就是说,若父线程优先级为8,则其子线程的初始优先级为8。 当需要改变线程的优先级时,可以通过调用setPriority方法来实现,下面为该方法的签名: public final void setPriority(int newPriority),9.3.3 线程的让步,实际运行中有时需要使当前运行的线程让出CPU,使其他线程得以执行,这时就需要使用

9、线程让步的操作。线程让步包括两种方式。 线程只是让出当前的CPU资源,具体将CPU让给谁不确定。 线程将给指定的线程让步,指定的线程没有完成,其绝不恢复执行。 本小节将对这两种让步的方式进行详细的介绍,具体内容如下。 1使用yield方法 2使用join方法,9.3.4 守护线程,前面已经提过,其实在Java中根本没有单线程程序,就算开发人员只开发了主线程,后台还有很多辅助线程,比如线程调度、内存管理等。这些在后台运行的线程一般称之为守护线程,本小节主要介绍如何开发自己的守护线程。 开发守护线程与普通线程没有很大的区别,只要对调用线程对象的setDaemon方法进行设置即可,该方法的签名如下。

10、 public final void setDaemon(boolean on),9.4 线程的同步,多线程程序中,由于同时有多个线程并发运行,有时会带来严重的问题,甚至引发错误。例如,一个银行账户在同一时刻只能由一个用户操作,如果两个用户同时操作很可能会产生错误。为了解决这些问题,在多线程开发中就需要使用同步技术,本节将对这方面的知识进行详细的介绍。,9.4.1 同步方法简介,同步方法是指用synchronized关键字修饰的方法,其与普通方法的不同是进入同步方法执行的线程将获得同步方法所属对象的锁,一旦对象被锁,其他线程就不能执行被锁对象的任何同步方法。也就是说,线程在执行同步方法之前,首

11、先试图获得方法所属对象的锁,如果不能获得锁就进入对象的锁等待池等待,直到别南叱淌头潘浠竦盟拍苤葱小 下面给出了声明同步方法的基本语法。 synchronized 方法名(参数列表) throws /同步方法的方法体 ,9.4.2 简单使用同步方法,上一小节介绍了同步方法与对象锁的基本知识,本小节将通过一个完整的例子进行说明。,9.4.3 线程同步调度的方法,通过前面的介绍可以知道,线程在退出同步方法时将释放方法所属对象的锁。但这并不是全部,在同步方法中还可以使用特定的方法对线程进行调度,这些方法在处理资源的同步与互斥问题时非常有效。,9.4.4 同步的语句块,前面的几个小节介绍了同步的方法,同

12、步的方法在同一时刻只能锁定一个对象(同步方法所属的对象),但在并发执行中有时需要锁定的对象远不只一个。另外,同步将影响程序的执行性能,应该尽量减少程序同步的区域,提高程序的并发性,而同步方法是无法精确指定同步区域的。 要想解决上述问题,就需要使用同步的语句块,其基本语法如下。 synchronized() /需要进行同步的代码 ,9.4.5 线程的死锁,任何并发运行的系统中,当有多个访问者并发访问多个互斥的资源时,就有可能造成死锁的现象。如果系统的设计不完善,在Java中进行多线程开发时也有可能造成死锁。Java中死锁的含义是:“线程之间互相等待对方释放资源对象的锁,而每个线程又持有其他线程需

13、要的锁,造成几个线程处在没有必要的永久等待当中,程序无法继续运行”。,9.4.5 线程的死锁,9.5 进程同步经典示例,资源的同步与互斥问题中,最典型的就是“生产者消费者”问题。“生产者消费者”问题的具体含义是,系统中有很多生产者和消费者并发工作,生产者负责生产资源,消费者消耗资源。当消费者消费资源时,如果资源不足,则需要等待,反之当生产者生产资源时,若资源以满,则也需要等待。另外,同一时刻只能有一个生产者或消费者进行操作。,9.5.1 “生产者消费者”案例的框架,本书将以在Java中用多线程实现“生产者消费者”问题模型为例,来讨论上一节所介绍的线程调度方法的使用。下面首先分别给出了“资源容器

14、”、“生产者”、“消费者”类的代码。 提示:“生产者消费者”模型也是很好的解决多线程共享一个资源时冲突问题的解决方案,读者一定要深入理解,在实际开发中进行应用。 1资源类 2生产者类 3消费者,9.5.2 “生产者消费者”案例的实际运行,上一小节中给出了“生产者消费者”案例中需要使用的功能类代码,本小节将通过实际运行的情况介绍生产者与消费者线程在运行时是如何协作的。,9.5.3 notify方法的使用,在上一小节的“生产者消费者”案例中,通知等待池中的等待线程使用的是notifyAll方法。本小结将结合“生产者消费者”案例介绍notify方法的使用。,9.6 volatile关键字的含义与使用,前面章节介绍的基本数据类型中,有两种是64位的,long与double。而目前使用的机器大部分是32位的,也就是说每次只能处理32位的数据。这样在处理64位数据时就要处理两次,如果多线程并发处理数据就有可能引发错误。,9.6 volatile关键字的含义与使用,9.7 小结,本章介绍了Java中进行多线程开发的基本知识,包括线程的调度、同步,以及对线程的一些实用的操作方法。通过本章的学习,读者应该基本掌握Java中多线程程序的开发,可以在实际开发中应用多线程技术开发出并发处理的程序,为学习线程的高级开发打下良好的基础。,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号