1、Java技术与应用,西安交大 卫颜俊 2007年5月 电子信箱:Mr.J,异常、线程和定时器 (第1011章),主要内容,JBuilder2006介绍 案例的面向对象程序设计 异常处理 线程设计,1. JBuilder2006介绍,Java IDE,2005年由美国著名的软件开发工具厂商Borland公司,推出的新一代的集成化的Java开发工具(IDE)集成了几乎所有的Java技术,涵盖了软件开发生命周期的各个过程,是一款强大的Java企业级开发平台。 ,主要特点,P2P协作开发、支持最新的Java技术和最JDK新版本、高开发效率、IDE可用性大大提高、高级编辑器、调试功能、Web开发、应用服
2、务器支持、J2EE/EJB开发、团队开发、程序诊断、Web服务、移动应用、优化集成、XML、库更新和开放式工具等。 ,主要功能,主要功能分布在主窗口的各个区域,包括 工程格、文件标签、内容格、结构格和状态格等, 组件板、组件树、设计标签、设计台和观察器等。 ,2.案例的面向对象 程序设计,虚拟酒店点菜系统,功能,客人使用账号和密码登录成功以后,可以随意点菜,由系统将点好的菜单传送到厨师处。还可以查看厨师为自己炒好的菜单,并食用; 厨师使用账号和密码登录成功以后,可以看到所有客人向其点的菜单,并炒好任意一个菜,由系统将炒好的菜单传送到客人; 系统管理员可以统计每一位客人的消费金额,和每一位厨师的
3、收入金额。 ,设计结果,厨师类、菜系类、菜谱类、客人类、菜单类和各个类的相关操作,3.异常处理,问题的起因,分母=0 负数开方 数组下标超界 类型转换(String -int,float) 空对象引用其它:类找不到,方法找不到,文件不存在,I/O,数据库,网络,安全性, ,异常处理机制之1-throw,当Java程序在运行过程中出现异常时,就会生成一个异常对象,并提交给运行系统,这种异常的产生和提交过程称为异常抛出(throw)。 ,异常处理机制之2-catch,当运行系统获得这个异常对象时,它就会沿着方法的调用顺序逐层回溯,去寻找处理这一异常对象的代码或方法。如果找到,运行系统会把当前这个异
4、常对象交给这个方法进行处理,这一过程称为异常捕获(catch);反之,如果找不到合适的方法,运行系统将终止,相应的Java程序也将结束运行。 ,异常处理机制之3-throws,如果一个方法无法应对所出现的这个异常对象,还可以在方法声明部分中进行异常抛出声明(throws),将异常交给上一层方法来处理。程序员自己也可以首先定制异常和自行抛出异常,然后交给运行系统来处理。 ,异常层次,java.lang.Objectjava.lang.Throwablejava.lang.Errorjava.lang.Exceptionjava.lang.RuntimeException ,异常类介绍,Throw
5、able 类 不可检查类 Error类及其子类和RuntimeException类及其子类都是不可检查类,Error类称为错误类,RuntimeException类称为运行异常类,它为Exception类的子类, 可检查类 而其它Exception子类都是可检查类。 一般更多地考虑可检查的异常和一部分运行异常,Error的子类,Exception的子类,RuntimeException的子类,常用的异常类,问题的答案,分母=0 ArithmeticException 负数开方 ArithmeticException 数组下标超界 ArrayIndexOutOfBoundsException 类
6、型转换 NumberFormatException 空指针 NullPointerException ,异常处理的格式,捕获异常try/正常执行语句 catch(异常类1 异常参数1)/异常处理语句1 catch(异常类2异常参数2)/异常处理语句2 catch(异常类n异常参数n)/异常处理语句n finally/收尾语句 ,声明抛出异常(由JVM或Java类库生成)方法修饰符 返回类型 方法名(参数说明列表) throws 异常类列表方法体 其中异常类列表可以是多个异常类名。 在main方法中使用throws则抛弃异常。抛出异常异常类名 异常对象名=new异常类名(); throw 异常对
7、象名; ,问题的解决,使用异常处理进行捕获和抛出 try catch finally throw throws ,用户自定义异常格式,系统类库中已定义好若干标准Exception子类用来处理一些常见异常用户程序也可以自定义Exception子类处理特殊问题,举例: 【例10-1】,【例10-1】只接受命令行参数的非零整数值,而对其它情况作为异常来处理。可能会出现以下异常: ArithmeticException ArrayIndexOutOfBoundsException NumberFormatException Exception ,举例: 【例10-2】,【例10-2】异常的嵌套处理 。
8、算法说明: 当参数值为“除法”和“空指针“时,由运行系统自动抛出异常,而当参数值为“测试“时,由程序自己抛出异常,其它值为正常。 ,举例: 【例10-3】,【例10-3】将百分制转换为五分制,超过0和100的作为异常 。 ,4.线程设计,进程与线程概念,进程 程序的一次执行,系统进行资源申请、调度和独立运行的单位 具有就绪、运行和停止等三个主要状态以及优先级,优先级高的进程首先投入运行。 线程 包含指令序列,是程序运行的基本单位,它比进程更小,仅作为CPU调度单位,只拥有必不可少的资源 具有就绪、阻塞(等待)和执行三种基本状态和优先级。 ,进程与线程的关系,进程是线程的容器,它从来不执行任何东
9、西,如果需要进程完成某项操作,它必须拥有一个在它的环境中运行的线程以负责执行包含在进程的地址空间中的代码。 每个进程至少拥有一个线程,来执行进程的地址空间中的代码。 当某个程序启动时,将建立一个进程,它拥有这个程序所需要的内存和其它资源等,操作系统会自动创建这个进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。 ,多线程,多线程间共享数据和代码空间,交换数据信息 一般,一个程序执行当中会有多个线程在运行。 单CPU如何实现多线程的并行执行 划分极短的CPU时间片 A 各线程轮流占用一个时间片 B,进程的管理,每个Java应用程序的运行都必然建立一个Runtime类的实例,以保持应用
10、程序与其运行环境的联系 通过Runtime类的getRuntime方法可以获取当前的运行时状态,exec方法执行外部进程。 Process类的实例代表一个进程,它一般由Runtime类的exec方法来获得 ,举例: 【例11-1】,【例11-1】在Java程序中执行外部命令 ,定时器,线程由操作系统调度 而定时器程序自己可以把握Timer类 用于安排以后在后台线程中执行的任务。 Timer() 创建一个新计时器。 cancel() 终止此计时器,丢弃所有当前已安排的任务。 schedule(TimerTask task, long delay, long period) 安排指定的定时器任务从
11、指定的延迟后开始进行重复的固定延迟执行。 ,定时器任务,TimerTask类 由Timer安排为一次执行或重复执行的任务,是一个抽象类,需要继承得到其子类,并实现其run方法,以指定定时器任务要执行的操作 。run方法的格式如下: public void run() ,定时处理的步骤, 建立定时器任务类,并编写run方法,比如:class MyTimerTask extends TimerTask public void run() 构造定时器任务类的对象,比如:MyTimerTask myTimerTask = new MyTimerTask(); 构造定时器类的对象,比如:Timer my
12、Timer = new Timer(); 调用定时器的schedule方法,传递定时器任务对象,初始延迟和间隔时间等三个参数,启动定时器任务 必要时,使用定时器的cancel方法来结束定时器的执行 ,举例: 【例11-2】,【例11-2】建立具有两个计数器的程序,它们分别完成递增和递减计数算法简述: 当两个定时器任务中的计数器值接近时,结束该定时器的执行并退出程序。 ,产生一个线程,主(缺省)线程: Application: main( ) Applet: 浏览器执行线程用户自定义线程(多线程的实现)创建用户的Thread子类, 继承类Thread 在Thread子类的run( )方法中定义用
13、户线程工作 在主线程中start()用户创建的Thread子类的实例,该线程被调度时系统自动执行run( )方法 使用户类实现Runnable接口(含方法run() 用本类实例作参数,创建Thread类的实例,继承本类中的run()方法,实现子线程的任务 在用户类的方法中start()所创建的Thread实例 ,继承类Thread,Thread的对象无法直接使用,而通过:public void run() 方法,它是线程的主方法,线程执行的第一件事 与Application的main()类似。run()缺省为空,可以覆盖。举例: public class MyUsefulThread exte
14、nds Thread public void run() /. 通过调用start()方法来启动线程: MyUsefulThread t = new MyUsefulThread(); t.start(); ,实现接口Runnable,使用Runnable 接口增加对类的线程支持, 而不必继承类Thread,其中只声明了一个方法:public void run() ;产生线程有两步:实现接口Runnable实现方法run() 举例: public class MyUsefulThread implement Runnablepublic void run() /. 通过调用start()方法来
15、启动线程: Thread t = new Thread(new MyUsefulThread(); t.start(); ,举例: 【例11-3】,【例11-3】使用两个线程分别显示指定的不同范围内的所有整数。 ,线程的状态与调度,Java提供了线程调度器监控就绪状态中的所有线程。 按照线程的优先级来决定调度哪些线程(优先级由高到低)。 线程的调度是抢先式的(较高优先级的线程代替当前线程进入就绪状态)。 同优先级的线程采用轮转法。Thread.MIN_PRIORITY- Thread.MAX_PRIORITY(110) 线程的缺省优先级为Thread.NORM_PRIORITY(5)。 线程创
16、建时继承父线程的优先级 方法int getPriority()取得线程的优先级,void setPriority(int newPriority)设置线程的优先级。 ,线程的五个状态,线程同步的概念,问题的提出 线程对内存、数据的共享 线程执行的不确定性引起执行结果的不稳定 问题的解决 同步: 用synchronized关键字前缀给针对共享资源的操作加锁;同步方法、同步块使用synchronized来实现一次只能有一个线程的一个方法或代码块执行的功能。 管程:最先进入同步块的线程拥有该块的管程,其他线程将不能执行该块代码, 不能改变共享变量, 直到原线程结束或调用wait()释放管程,线程同步
17、的实现,wait():令当前线程挂起并放弃管程,同步资源解锁,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问 notify()唤醒正在排队等待资源管程的线程中优先级最高者,使之执行并拥有资源的管程wait() + notify() + 标志变量:可协调、同步不同线程的工作 sleep():休眠时并不放弃监控器(monitor) ,具体编程时,使用关键字synchronized(即同步控制) 类方法的格式: synchronized returnType methodName(paramList) 使用synchronized来实现一次只能有一个线程执行一个方法或代码块的功能
18、。 并通过方法wait()和notify()来实现线程间的同步通讯。 ,举例: 【例11-5】,建立队列应用的多线程应用程序。由一个线程建立队列,另两个线程分别提取其中大于0.5和小于等于0.5的数,不符合要求的数将被扔掉。 算法简述: 使用LinkedList类建立队列结构;定义工作队列类,该类的对象作为三个线程的共享变量,在其中定义队列结构的成员变量(queue),以及入队(addWork)和出队(getWork)成员方法。 定义一个入队线程类,并构造其一个线程不断产生随机数入队 定义一个出队线程类,构造其两个线程不断出队,并分别根据出队数值大于0.5和小于等于0.5,将数值显示出来。 ,
19、线程的死锁,死锁 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁 解决方法 专门的算法、原则 尽量减少同步资源的定义,综合例子,【例11-6】使用两个线程并行计算的值。算法简述:普通的计算方法如下: i=1,u=1,s=1; 第i个通项u=u*i/(2*i+1),前i项的和s=s+u,接着,i=i+1,继续下去; i=i+1,当i不超过给定的n时,转到;否则结束。 ,综合例子(续),采用两个线程并行计算时, 可以将第i个通项的计算交给一个线程进行, 而前i项之和的计算交给另一个线程去做 通过wait、notify、sleep和状态变量等手段保证计算的同步。 计算中还应使用BigDecimal类,以及其multiply和add方法进行大浮点数的乘法与加法运算。 ,作业3题目,实验3题目,本讲结束!,谢谢!,