收藏 分享(赏)

08ChapterJava基础课件第八章.ppt

上传人:fmgc7290 文档编号:9190786 上传时间:2019-07-29 格式:PPT 页数:56 大小:369KB
下载 相关 举报
08ChapterJava基础课件第八章.ppt_第1页
第1页 / 共56页
08ChapterJava基础课件第八章.ppt_第2页
第2页 / 共56页
08ChapterJava基础课件第八章.ppt_第3页
第3页 / 共56页
08ChapterJava基础课件第八章.ppt_第4页
第4页 / 共56页
08ChapterJava基础课件第八章.ppt_第5页
第5页 / 共56页
点击查看更多>>
资源描述

1、第8章 异常处理与多线程,内容提要:Java异常 异常的处理 线程概念 线程的创建 线程的状态与控制 线程的优先级、调度和管理 线程组 线程的同步,异常处理,Java异常的概念和处理机制 Java异常的分类 异常的捕获、处理和抛出 使用用户自定义异常,8.1 Java异常,Java程序运行过程中所发生的异常事件可分为两类: 错误(Error):JVM系统内部错误、资源耗尽等严重情况 异常(Exception): 其它因编程错误或偶然的外在因素导致的一般性问题,例如: 对负数开平方根 空指针访问 试图读取不存在的文件 网络连接中断,Java异常举例(1),程序名称:ExceptionTest1.

2、java public class ExceptionTest1public static void main(String args) String name =“Bill“,“Bob“,“David“;for(int i=0;i5;i+) System.out.println(name i);System.out.println(“n“+“this is the end“); ,异常处理举例(1),程序ExceptionTest1.java运行结果:,常见异常,RuntimeException 错误的类型转换 数组下标越界 空指针访问 IOExeption 从一个不存在的文件中读取数据 越

3、过文件结尾继续读取 连接一个不存在的URL,8.1.2异常处理机制,Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。 如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。 程序员通常只能处理异常(Exception),而对错误(Error)无能为力,Java异常类层次,Java异常举例(2),public class Exceptio

4、nTest2public static void main(String args) String name =“Bill“,“Bob“,“David“;try for(int i=0;i5;i+) System.out.println(name i); catch(java.lang.ArrayIndexOutOfBoundsException e) System.out.println(“错误类型:下标越界“);System.out.println(“this is the end“); ,异常处理举例(2),程序ExceptionTest1.java运行结果:,8.2 异常的处理,如果发

5、生了运行时错误,运行时系统就会产生一个与该错误相对应的异常类对象,Java为它提供了默认的异常处理程序。 当程序在运行时产生了非运行时错误,则有两种处理方式: 一种方式是自己处理,使用try-catch-finally语句来捕获并处理异常对象 另一种方式是方法不需要处理它生成的异常,而是向上传递,由调用它的方法来处理,使用throw语句声明它可以抛出的异常,而不捕捉它们。,8.2.1捕获异常,捕获异常是通过try-catch-finally语句实现的。try/可能产生违例的代码 catch( ExceptionName1 e )/当产生ExceptionName1型违例时的处置措施 catch

6、( ExceptionName2 e )/当产生ExceptionName2型违例时的处置措施 finally/无条件执行的语句 ,捕获异常,try 捕获异常的第一步是用try语句块选定捕获异常的范围。 catch 在catch语句块中是对异常对象进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。 getMessage( ) 方法,用来得到有关异常事件的信息 printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。,捕获异常,finally 捕获异常的最后一步是

7、通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。 finally语句是任选的,IOException异常处理举例(1),import java.io.*; public class ExceptionTest4 public static void main(String args) FileInputStream in=new FileInputStream(“myfile.txt“);int b;b = in.read();while(b!= -

8、1) System.out.print(char)b);b = in.read();in.close(); ,IOException异常处理举例(2),程序ExceptionTest4 .java编译结果:,8.2.3声明异常,声明抛出异常是Java中处理异常的第二种方式 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理 声明抛出异常: public void readFile(String file) throws FileNotFoundException / 读文件的操作可

9、能产生FileNotFoundException类型的违例FileInputStream fis = new FileInputStream(file);,声明抛出举例,import java.io.*; public class ExceptionTest5public static void main(String args)ExceptionTest5 t = new ExceptionTest5 ();tryt.readFile();catch(IOException e)System.out.println(e.getMessage (); public void readFile(

10、) throws IOException FileInputStream in=new FileInputStream(“myfile.txt“);int b; b = in.read();while(b!= -1) System.out.print(char)b);b = in.read();in.close(); ,声明抛出举例,程序ExceptionTest5.java运行结果:,8.2.3 抛出异常,Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要需要人工创建并抛出 首先要生成异常对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。 IO

11、Exception e =new IOException(); throw e; 可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:throw new String(“want to throw“);,抛出异常举例,import java.io.*; public class Testthrowstatic void readArray(int a,int b) throws ArrayIndexOutOfBoundsException if (ab)throw new ArrayIndexOutOfBoundsException (“很可惜超过数组范围

12、!“);elseint array=new inta;arrayb=4;System.out.println(“数组赋值成功!“); public static void main(String args)tryreadArray(5,4);readArray(4,5);catch(ArrayIndexOutOfBoundsException e)System.out.println(“异常提示:“+e.getMessage (); ,抛出异常举例,程序Testthrow.java运行结果:,8.2.4重载方法声明抛出异常原则,重写方法不能抛出比被重写方法范围更大的异常类型,public cl

13、ass A public void methodA() throws IOException public class B1 extends TestA public void methodA() throws FileNotFoundException public class B2 extends TestA public void methodA() throws Exception ,8.2.5自定义异常类,用户自定义异常类MyException,用于描述数据取值范围错误信息: class MyException extends Exception private int idnumb

14、er;public MyException(String message, int id) super(message);this.idnumber = id; public int getId() return idnumber; public class ExceptionUserpublic void regist(int num) throws MyException if (num 0) ,8.2.5自定义异常类,System.out.print(“登记人数“+num);throw new MyException(“人数为负值,不合理“,3); public void manager

15、() try regist(-100); catch (MyException e) System.out.print(“登记失败,出错种类“+e.getId();System.out.print(“本次登记操作结束“);public static void main(String args)ExceptionUser t = new ExceptionUser ();t.manager(); ,8.3线程概念,线程是一个程序内部的顺序控制流。 线程和进程 每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。 线程: 轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行

16、栈和程序计数器(PC),线程切换的开销小。 多线程: 在同一应用程序中有多个顺序流同时执行 多任务: 在操作系统中能同时运行多个任务(程序),8.3.2 Java对多线程的支持,Java的线程是通过java.lang.Thread类来实现的。 每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。,8.4线程的创建-通过实现Runnable接口,class TestThread2 public static void main(String args) Athread a = new Athread ();Thread t = new Th

17、read(a);t.start(); class Athread implements Runnable public void run() for(int i=0; i5; i+) System.out.println(“I am B“+i); ,8.4线程的创建 -继承Thread类,class TestThread1 static AThread aThread;public static void main(String args) aThread=new AThread() ;/创建线程。 aThread.start(); /线程开始运行后 class AThread extends

18、 Thread public void run() for(int i=0;i=2;i+) System.out.println(“I am A“+i);trysleep(600);catch(InterruptedException e) ,两种创建线程方法的比较,使用Runnable接口可以从其他类继承;保持程序风格的一致性。直接继承Thread类不能再从其他类继承;编写简单,可以直接操纵线程,无需使用Thread.currentThread()。,8.5线程的状态与控制,在生命周期中,一个线程具有创建、就绪状态、运行状态、阻塞和终止状态五种状态,Thread类中的方法可以改变线程的状态。

19、,8.5线程的状态与控制,线程控制基本方法,改变线程状态,使用start() 方法启动线程 启动线程是使线程进入到就绪状态,并不一定立即开始执行该线程 使用sleep () 方法使线程进入阻塞状态,即线程暂时不再继续执行。睡眠时间过后再进入就绪状态。,线程状态转换举例,public class TestThread3public static void main(String args) Athread r = new Athread();Thread t = new Thread(r);t.start(); class Athread implements Runnable public v

20、oid run() for(int i=0; i5; i+) if(i%2=0 ,join方法用法举例,public class TestThread5 public static void main(String args)Athread a = new Athread();Thread t = new Thread(a);t.start();tryt.join();catch(InterruptedException e)for(int i=0;i3;i+)System.out.println(“main主线程:“ + i); class Athread implements Runnab

21、le public void run() for(int i=0;i3;i+) System.out.println(“Athread线程: “ + i); ,8.6线程的优先级、调度和管理,线程的优先级用数字来表示,范围从1到10,一个线程的缺省优先级是5 Thread.MIN_PRIORITY = 1Thread.MAX_PRIORITY = 10Thread.NORM_PRIORITY = 5 使用下述线方法获得或设置线程对象的优先级int getPriority();void setPriority(int newPriority);,线程的调度,Java提供一个线程调度器来监控程序中

22、启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪些线程来执行。 setPriority(int)方法设置优先级 多数线程的调度是抢先式的。 时间片方式 非时间片方式,下面几种情况下,当前线程会放弃CPU: 线程调用了yield(),sleep()方法主动放弃; 由于当前线程进行I/O访问,外存读写,等待用户输入等操作,导致线程阻塞; 为等候一个条件变量,线程调用wait()方法; 抢先式系统下,有高优先级的线程参与调度;时间片方式下,当前时间片用完,有同优先级的线程参与调度。,线程的调度,8.7线程组,在 Java 中,每个线程都是一个线程组的成员,线程组把多个线程集合为一

23、个对象. java.lang包中ThreadGroup类实现了对线程组的创建和对线程组的操作. 对线程组的操作就是对线程组中所有成员的操作。 在Java应用程序中,最高层的线程组是main 。 Java 允许我们对一个线程组中的所有线程同时进行操作。,8.7.2 线程组的创建,创建线程组有两种方法: (1)创建一个名字为name的线程组。 public ThreadGroup(String name); (2)在线程组parent中创建一个线程组name。 public ThreadGroup(ThreadGroup parent, String name);,8.7.3线程组的属性,1线程组

24、的名字 public final String getName( ); /返回线程组的名称 2线程组的父类 public final ThreadGroup getParent( ); /返回线程组的父类 3线程组的优先级 public final void getMaxPriority( ); /返回线程组的最大优先级 public final void setMaxPriority( int n); /设置线程组的最大优先级,8.7.4线程组的管理,(1)返回当前线程组中活动线程的个数 public int activeCount( ) ; (2)将当前线程组中活动的线程复制到线程数组或线

25、程组数组中 。 public int enumerate(Thread list ),8.8线程的互斥与同步,在Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。 每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。,关键字synchronized,关键字synchronized用法举例,public void push(char c)synchronized(this)dataidx=c;i

26、dx+;public char pop()synchronized(this)idx-;return dataidx;,关键字Synchronized,synchronized 除了象上面放在对象前面限制一段代码的执行外,还可以放在方法声明中,表示整个方法为同步方法。 public synchronized void push(char c) 如果synchronized用在类声明中,则表明该类中的所有方法都是synchronized的。 public synchronized class Stack,实现多线程的同步,class SyncStack /支持多线程同步操作的堆栈的实现priva

27、te int index = 0;private char data = new char6; public synchronized void push(char c)while(index = data.length)trythis.wait();catch(InterruptedException e)this.notify();dataindex = c;index+;public synchronized char pop()while(index =0)trythis.wait();catch(InterruptedException e)this.notify();index-;

28、return dataindex;,生产者-消费者问题,生产者:Consumer.java 消费者:Producer.java 栈:SyncStack.java 主程序:SyncTest.java,生产者-消费者问题(1),class Producer implements Runnable /生产者 SyncStack stack; public Producer(SyncStack s)stack = s; public void run()for(int i=0; i3; i+)char c =(char)(Math.random()*26+A);stack.push(c);System

29、.out.println(“生产:“+c);try Thread.sleep(int)(Math.random()*100);catch(InterruptedException e) ,class Consumer implements Runnable /消费者: SyncStack stack; public Consumer(SyncStack s)stack = s; public void run()for(int i=0;i20;i+)char c = stack.pop();System.out.println(“消费: “+c);try Thread.sleep(int)(M

30、ath.random()*1000);catch(InterruptedException e) ,生产者-消费者问题(2),主程序:public class SyncTestpublic static void main(String args)SyncStack stack = new SyncStack();Runnable p=new Producer(stack);Runnable c = new Consumer(stack);Thread t1 = new Thread(p);Thread t2 = new Thread(c);t1.start();t2.start();,生产者

31、-消费者问题(3),例题8-1:写一个程序,启动20个线程,每个线程内包含1个1000次循环,每次循环将一个共享整型变量的值增加50。观察最后的计算结果。,例题8-2:写一个程序模拟商品销售过程。设有一群顾客要在一家商场购买一种工艺品。工艺品每个价值50元。顾客手中有50元、100元等不同面值纸币。持50元纸币的顾客可以立即买到工艺品,持100元的顾客需要看销售员是否有零钱找,若有则也能立即买到,若没有则必须等待。,8.8.4 死锁,多线程如果同步不当就会造成线程间的死锁。 死锁一般是由于每个线程所需要的资源被其他线程占用,这样相互等待其他线程释放资源而造成的。 例如两个线程分别等待对方占有的一个资源,于是两者都不能执行而处于永远等待状态,就产生了死锁。 死锁原因不是系统资源不足,而是由于调度的不当的引起。,例题8-3:前1个例题在什么情况下可能产生死锁?,本章小结,本章主要介绍了Java程序中的异常处理机制和多线程技术。在异常机制部分,介绍了异常的概念、异常处理机制和异常类;介绍了捕获异常、声明异常、抛出异常和自定义异常类等异常处理方法。 在多线程技术部分介绍了线程的概念,线程的创建、线程的状态与控制;介绍了线程的优先级、调度和管理;介绍了线程组和线程的同步。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报